====================
FactoryBean接口_细节
====================
1 获取FactoryBean对象
applicationContext.getBean("conn")返回的是Connection对象而非ConnectionFactoryBean对象。
如果就想获得ConnectionFactoryBean对象怎么办?
applicationContext.getBean("&conn")返回的是ConnectionFactoryBean对象而非Connection对象。
例程:Injection
2 单例多例
如果FactoryBean的isSingleton()方法返回false,那么每次从getBean()方法得到的是不同的对象。
com.mysql.jdbc.JDBC4Connection@4b8ee4de
com.mysql.jdbc.JDBC4Connection@55634720
如果FactoryBean的isSingleton()方法返回true,那么每次从getBean()方法得到的是同一个对象。
com.mysql.jdbc.JDBC4Connection@4b8ee4de
com.mysql.jdbc.JDBC4Connection@4b8ee4de
例程:Injection
如果是共享型对象就返回true,否则返回false。
数据库连接对象不能共享,应该返回false。
数据库连接对象负责管理事务,在多个线程中共享同一个连接对象,会影响事务逻辑。
线程1 线程2。
| |
开启事务- |
| | __ |
操作 >|连| |
| |接|<--开启事务
操作 |对| 操作
| |象|<--提交事务
操作 >|__| |
| | |
提交事务- |
| |
v v
如果线程1和线程2共享同一个连接对象,线程2提交事务会将线程1中未完成的事务一并提交,这显然不对。
SqlSessionFactory是MyBatis提供的SQL会话工厂对象,重量级且线程安全,可共享。创建该对象的FactoryBean的isSingleton()方法应该返回true。
3 关闭SSL验证
运行Injection工程的ConnectionTest.test()测试用例,提示如下警告信息:
WARN: Establishing SSL connection without server's identity verification is not recommended.
在连接高版本MySQL时,默认情况下需要提供SSL证书,但我们并没有提供,因此给出警告。
该警告可以忽略,并没有什么影响。
如果一定要消除此警告,可以在连接数据库的URL中加上“useSSL=false”,显式地关闭SSL验证。
/src/main/java/cn/tedu/injection/ConnectionFactoryBean.java:
public class ConnectionFactoryBean implements FactoryBean {
...
@Override
public Connection getObject() throws Exception {
...
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/springdb?useSSL=false",
"root", "123456");
...
}
...
}
例程:Injection
4 依赖注入
在ConnectionFactoryBean类中:
public class ConnectionFactoryBean implements FactoryBean {
...
@Override
public Connection getObject() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/springdb?useSSL=false",
"root", "123456");
return conn;
}
...
}
用到了四个字符串:
"com.mysql.jdbc.Driver" - JDBC驱动的类名
"jdbc:mysql://localhost:3306/springdb?useSSL=false" - 连接MySQL数据库的URL
"root" - 连接MySQL数据库的用户名
"123456" - 连接MySQL数据库的密码
用到了就说明有依赖,有依赖就应该注入,而所谓注入就是配置文件->Set方法->成员变量。
/src/main/java/cn/tedu/injection/ConnectionFactoryBean.java:
public class ConnectionFactoryBean implements FactoryBean {
private String driver;
private String url;
private String username;
private String password;
public void setDriver(String driver) {
this.driver = driver;
}
public void setUrl(String url) {
this.url = url;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public Connection getObject() throws Exception {
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
...
}
/src/main/resources/applicationContext.xml:
例程:Injection
依赖注入的核心思想就是解耦合,说白了就是宁改配置文件不改Java代码。