??xml version="1.0" encoding="utf-8" standalone="yes"?>
spring是通过依赖注入(Dependency Injection )实现的IoC
IoC容器
* 必须被理的对象定义到spring配置文g?br />
* 必须定义constructor或者setterҎ(gu)Q让spring对象注入进?br />
AOP : Aspect Oriented Programming
spring带来?jin)一U编E方式,面向切面的编E?br />
AOP是一个概?br />
在一个程序中分离一个功能,q种功能的实现是与程序不相关的类?br />
同时能够使很多类׃nq个功能?br />
x(chng)是他的主要点Q要x(chng)某个功能Q要x(chng)切入炏V?br />
实现AOP?点:(x)
1、PointcutQ切入点Q是一个范?--表达?br />
2、AdviceQ具体实玎ͼ(j)功能攑ֈ那个Ҏ(gu)
spring对hibernate的支?br />
注入SessionFactory到spring配置文g?br />
<Bean id="SessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactory">
<property nema="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</Bean>
在网上看q很多解决mysqlq的帖子,可是写的不是|里|嗦p于复杂。其实ؕ码没那么复杂Q是|上的大侠们惛_?jin)。我研究q一D|子,ȝZ套自q解决Ҏ(gu)Q如果你q没解决qq我的Ҏ(gu)试一下。我的方案不是最好的Q却是最单易懂的。不信你试试?/p>
在用MYSQLӞ插入中文字符Q经怼(x)出现qQ中文全被用?代替。出现这U情늚原因Q多是字W集不匹配造成的?br /> 在MYSQL中,如果使用~省的字W集Q在建库、徏表时Q默认用的是latin1字符集,为ISO 8859-1西欧字符集。插入中文字W时Q与之不匚wQ就?x)出Cؕ码?/p>
要解x(chng)问题Q就必须手动数据库Server和Client的字W编码改为gb2312。配|方法如下:(x)
打开MYSQL安装目录下的my.ini文gQ找到如下段落:(x)
# CLIENT SECTION
# ----------------------------------------------------------------------
#
# The following options will be read by MySQL client applications.
# Note that only client applications shipped by MySQL are guaranteed
# to read this section. If you want your own MySQL client program to
# honor these values, you need to specify it as an option during the
# MySQL client library initialization.
#
[client]
port=3306
[mysql]
default-character-set=latin1
# SERVER SECTION
# ----------------------------------------------------------------------
#
# The following options will be read by the MySQL Server. Make sure that
# you have installed the server correctly (see above) so it reads this
# file.
#
[mysqld]
# The TCP/IP Port the MySQL Server will listen on
port=3306
#Path to installation directory. All paths are usually resolved relative to this.
basedir="D:/MySQL/MySQL Server 5.0/"
#Path to the database root
datadir="D:/MySQL/MySQL Server 5.0/Data/"
# The default character set that will be used when a new schema or table is
# created and no character set is defined
default-character-set=latin1
其中的default-character-set=latin1改ؓ(f)default-character-set=gb2312( 两个都改),然后重启MYSQL(特别注意Q以前徏立的数据库要重徏Q因Z前存储的数据~码方式为ISO-8859-1),q行MySQL Command Line ClientQ?br /> 输入show variables like 'character_set_%';可以查看数据库的字符~码如下Q?/p>
mysql> show variables like 'character_set_%';
+--------------------------+-----------------------------------------+
| Variable_name | Value |
+--------------------------+-----------------------------------------+
| character_set_client | gb2312 |
| character_set_connection | gb2312 |
| character_set_database | gb2312 |
| character_set_filesystem | binary |
| character_set_results | gb2312 |
| character_set_server | gb2312 |
| character_set_system | utf8 |
| character_sets_dir | D:\MySQL\MySQL Server 5.0\share\charsets|
+--------------------------+-----------------------------------------+
然后Q在E序中将q接数据库的URL改ؓ(f)jdbc:mysql://localhost:3306/databasename?useUnicode=true&characterEncoding=gb2312 可以了(jin)Q?strong>Q?amp;ampQ是代表xml中的&Q?/font>
q需要注意到是:(x)1.你的JSP面一定别忘(sh)(jin)加上~码方式<%@ page pageEncoding="GB2312"%>?/font>
2.把以前写qo(h)Ҏ(gu)?getbytesQiso-8859-1Q全L
最后记住,一定要重新导入或徏立数据库Q!Q?/font>
Singleton模式׃ؓ(f)我们提供?jin)这样实现的可能。用Singleton的好处还在于可以节省内存Q因为它限制?br /> 实例的个敎ͼ有利于Java垃圾回收Qgarbage collectionQ?/p>
使用Singleton注意事项Q?br /> 有时在某些情况下Q用Singletonq不能达到Singleton的目的,如有多个Singleton对象同时被不同的c?br /> 装入器装载;在EJBq样的分布式pȝ中用也要注意这U情况,因ؓ(f)EJB是跨服务器,跨JVM?/p>
单态模式的演化Q?br /> 单态模式是个简单的模式Q但是这个简单的模式也有很多复杂的东ѝ?/p>
一Q首先最单的单态模式,单态模?
import java.util.*;
class Singleton
{
private static Singleton instance;
private Vector v;
private boolean inUse;
private Singleton()
{
v = new Vector();
v.addElement(new Object());
inUse = true;
}
public static Singleton getInstance()
{
if (instance == null) //1
instance = new Singleton(); //2
return instance; //3
}
}
q个单态模式是不安全的Qؓ(f)什么说?Q因为没考虑多线E,如下情况
Thread 1 调用getInstance() Ҏ(gu)Qƈ且判断instance是nullQ然後进入if模块Q?br />
在实例化instance之前Q?br />
Thread 2抢占?jin)Thread 1的cpu
Thread 2 调用getInstance() Ҏ(gu)Qƈ且判断instance是nullQ然後进入if模块Q?br />
Thread 2 实例化instance 完成Q返?br />
Thread 1 再次实例化instance
q个单态已l不在是单?/p>
二,Z(jin)解决刚才的问题:(x)单态模?
public static synchronized Singleton getInstance()
{
if (instance == null) //1
instance = new Singleton(); //2
return instance; //3
}
采用同步来解冻Iq种方式解决?jin)问题,但是仔细分?br />
正常的情况下只有W一ơ时候,q入对象的实例化Q须要同步,
其它时候都是直接返回已l实例化好的instance不须要同步,
大家都知到在一个多U程的程序中Q如果同步的消耗是很大的,很容易造成瓉
三,Z(jin)解决上边的问题:(x)单态模?Q加入同?br />
public static Singleton getInstance()
{
if (instance == null)
{
synchronized(Singleton.class) {
instance = new Singleton();
}
}
return instance;
}
同步Ҏ(gu)块同步,而不使用函数同步Q但是仔l分析,
又回C(jin)模式一的状态,再多U程的时候根本没有解决问?/p>
四,Z(jin)对应上边的问题:(x)单态模?Q也是很多人采用的Double-checked locking
public static Singleton getInstance()
{
if (instance == null)
{
synchronized(Singleton.class) { //1
if (instance == null) //2
instance = new Singleton(); //3
}
}
return instance;
}
q样Q模式一中提到的问题解决?jin)。不?x)出现多ơ实例化的现?br />
当第一ơ进入的时候,保正实例化时候的单?在实例化后,多线E访问的时候直接返回,不须要进入同步模块,
既实C(jin)单态,又没有损失性能。表面上看我们的问题解决?jin),但是再仔l分析:(x)
我们来假象这中情况:(x)
Thread 1 :q入?/3位置Q执行new Singleton()Q但是在构造函数刚刚开始的时候被Thread2抢占cpu
Thread 2 :q入getInstance()Q判断instance不等于null,q回instanceQ?br />
Qinstance已经被newQ已l分配了(jin)内存I间,但是没有初始化数?
Thread 2 :利用q回的instance做某些操做,p|或者异?br />
Thread 1 :取得cpu初始化完?br />
q程中可能有多个U程取到?jin)没有完成的实例Qƈ用这个实例作出某些操做?br />
Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?br />
出现以上的问题是因ؓ(f)
mem = allocate(); //分配内存
instance = mem; //标记instance非空
//未执行构造函?thread 2从这里进?br />
ctorSingleton(instance); //执行构造函?br />
//q回instance
Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-
五,证明上边的假x(chng)可能发生的,字节码是用来分析问题的最好的工具Q可以利用它来分?br />
下边一D늨序:(x)Qؓ(f)?jin)分析方便,所以渐了(jin)内容Q?br />
字节码的使用Ҏ(gu)见这里,利用字节码分析问?/font>
class Singleton
{
private static Singleton instance;
private boolean inUse;
private int val;
private Singleton()
{
inUse = true;
val = 5;
}
public static Singleton getInstance()
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
得到的字节码
;asm code generated for getInstance
054D20B0 mov eax,[049388C8] ;load instance ref
054D20B5 test eax,eax ;test for null
054D20B7 jne 054D20D7
054D20B9 mov eax,14C0988h
054D20BE call 503EF8F0 ;allocate memory
054D20C3 mov [049388C8],eax ;store pointer in
;instance ref. instance
;non-null and ctor
;has not run
054D20C8 mov ecx,dword ptr [eax]
054D20CA mov dword ptr [ecx],1 ;inline ctor - inUse=true;
054D20D0 mov dword ptr [ecx+4],5 ;inline ctor - val=5;
054D20D7 mov ebx,dword ptr ds:[49388C8h]
054D20DD jmp 054D20B0
上边的字节码证明Q猜x(chng)有可能实现的
六:(x)好了(jin)Q上边证明Double-checked locking可能出现取出错误数据的情况,那么我们q是可以解决?br />
public static Singleton getInstance()
{
if (instance == null)
{
synchronized(Singleton.class) { //1
Singleton inst = instance; //2
if (inst == null)
{
synchronized(Singleton.class) { //3
inst = new Singleton(); //4
}
instance = inst; //5
}
}
}
return instance;
}
利用Double-checked locking 两次同步Q中间变?解决上边的问题?br />
Q下边这D话我只能简单的理解Q翻译过来不好,所以保留原文,list 7是上边的代码Qlist 8是下边的
The code in Listing 7 doesn't work because of the current definition of the memory model.
The Java Language Specification (JLS) demands that code within a synchronized block
not be moved out of a synchronized block. However, it does not say that
code not in a synchronized block cannot be moved into a synchronized block.
A JIT compiler would see an optimization opportunity here.
This optimization would remove the code at
//4 and the code at //5, combine it and generate the code shown in Listing 8:Q?br />
-------------------------------------------------
list 8
public static Singleton getInstance()
{
if (instance == null)
{
synchronized(Singleton.class) { //1
Singleton inst = instance; //2
if (inst == null)
{
synchronized(Singleton.class) { //3
//inst = new Singleton(); //4
instance = new Singleton();
}
//instance = inst; //5
}
}
}
return instance;
}
If this optimization takes place, you have the same out-of-order write problem we discussed earlier.
如果q个优化发生Q将再次发生上边提到的问题,取得没有实例化完成的数据?br />
-------------------------------------------------
以下部分Z(jin)避免我翻译错误误导打Ӟ保留原文
Another idea is to use the keyword volatile for the variables inst and instance.
According to the JLS (see Resources), variables declared volatile are supposed to
be sequentially consistent, and therefore, not reordered.
But two problems occur with trying to use volatile to fix the problem with
double-checked locking:
The problem here is not with sequential consistency.
Code is being moved, not reordered.
Many JVMs do not implement volatile correctly regarding sequential consistency anyway.
The second point is worth expanding upon. Consider the code in Listing 9:
Listing 9. Sequential consistency with volatile
class test
{
private volatile boolean stop = false;
private volatile int num = 0;
public void foo()
{
num = 100; //This can happen second
stop = true; //This can happen first
//...
}
public void bar()
{
if (stop)
num += num; //num can == 0!
}
//...
}
According to the JLS, because stop and num are declared volatile,
they should be sequentially consistent. This means that if stop is ever true,
num must have been set to 100.
However, because many JVMs do not implement the sequential consistency feature of volatile,
you cannot count on this behavior.
Therefore, if thread 1 called foo and thread 2 called bar concurrently,
thread 1 might set stop to true before num is set to 100.
This could lead thread 2 to see stop as true, but num still set to 0.
There are additional problems with volatile and the atomicity of 64-bit variables,
but this is beyond the scope of this article.
See Resources for more information on this topic.
单的理解上边q段话,使用volatile有可能能解决问题Qvolatile被定义用来保正一致性,但是很多虚拟?br /> q没有很好的实现volatileQ所以用它也会(x)存在问题?/p>
最l的解决Ҏ(gu)Q?br />
Q?Q,单态模?Q用同步方?br />
Q?Q,攑ּ同步Q用一个静(rn)态变量,如下
class Singleton
{
private Vector v;
private boolean inUse;
private static Singleton instance = new Singleton();
private Singleton()
{
v = new Vector();
inUse = true;
//...
}
public static Singleton getInstance()
{
return instance;
}
}
但用静(rn)态变量也?x)存在问题,问题?q篇文章
而且如在文章开头提到的Q用EJB跨服务器Q跨JVM的情况下Q单态更是问?/p>
好了(jin)是不是感觉单态模式根本没法用了(jin)Q其实上辚w是特D情况,q中Ҏ(gu)情况的出现是有条件的Q只?br /> Ҏ(gu)你的具体应用Q回避一些,p解决问题Q所以单态还是可以用的。但是在使用前慎重,自己考虑好自?br /> 的情况适合哪种情况?nbsp;
Object是所有类的父cR?br /> java.lang.String也是l承自java.lang.Object中?/span>
先比较一?个类的toString()、equals()? = Q很多面试题都有Q,再来说一下String 的特D?/span>
2个类toString()的比较:(x)
查阅API文档Q?br />
说明Stringc重写了(jin)Object的toStringҎ(gu)?br />
"=="是比?个对象的引用是否指向同一个地址Q如果是比较2个基本类型,那么是比较2个值是否相{?br /> 我new?个Dogc,他们2个对象的栈引用肯定不能指向同一个堆地址。第二个String对象"=="的比较也是同样道理。所以都q回?jin)false(W三个比较体C(jin)String的特D类Q等下说??/span>
查阅jdk的源代码Q?equals"在Object中定义ؓ(f)
q就表示一个类如果没有重写该方法的话,它就是比较两个的引用是否指向?jin)同一个地址Q和"=="比较是一致的Q?br />
cd里的cd本都重写的该Ҏ(gu)Q所以是比较2个对象的内容是否一L(fng)QStringҎ(gu)重写?jin)该?gu)Q所以第二个equals比较q回tureQ,对于外面自己自定义的c,则需要自己重写该Ҏ(gu)来达到内Ҏ(gu)否相{的逻辑?/span>
Ҏ(gu)对象String的equals()? =比较Q?br />
String s = newString("abc");和String s = "abc";
首先2个对象在内存分布上是不一L(fng)。第2个对象是s的栈引用指向数据片段区的地址Q存攑֭W串帔RQ静(rn)态成员变量)(j)。第1个new出来的对象是s的栈引用指向堆中的地址Q存攑֜堆中Q。通过API文档Q新创徏的字W串对象s是该参数字符Ԍ"abc"Q的副本?br />
所以如代码所表示Q?=="比较是不一L(fng)QequalsҎ(gu)׃String重写?jin),比较是字W序列?/span>
String s1 = "abc" ?nbsp; String s2 = "abc"比较Q?br />
"=="和equalsҎ(gu)都返回tureQ?br />
s1分配?jin)字W常?abc"Q那么再?abc"要引用给对象Q都不会(x)再分配内存空间了(jin)?br />
所以s1 和s2 指向的空间相同,内容也相同?/span>