关键词:Spring | 复杂对象
本专栏通过理论和实践相结合,系统学习框架核心思想及简单原理,原创不易,如果觉得文章对你有帮助,点赞收藏支持博主 ✨

可以直接 new 构造方法来创建的对象,就是简单对象,反射底层一样会调用构造方法
不能直接通过 new 构造方法创建的对象
举例:常见的 jdbc 中的 Connection 对象,mybatis 中的 SqlSessionFactory 对象
现在想把 jdbc 中的 Connection 对象也交给 Spring 创建
首先,在 pom 中引入 MySQL 驱动 jar 包
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.48version>
dependency>
开发自己的 FactoryBean
package factorybean;
import org.springframework.beans.factory.FactoryBean;
import java.sql.Connection;
import java.sql.DriverManager;
public class ConnectionFactoryBean implements FactoryBean<Connection> {
// 写创建复杂对象的代码
@Override
public Connection getObject() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/zhou", "root", "root");
return conn;
}
// 返回创建对象的Class对象
@Override
public Class<?> getObjectType() {
return Connection.class;
}
// 是否为单例
@Override
public boolean isSingleton() {
return true;
}
}
spring配置文件
<bean id="conn" class="factorybean.ConnectionFactoryBean"/>
测试
@Test
public void t3() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring.xml");
Connection conn = (Connection) context.getBean("conn");
System.out.println(conn);
}
com.mysql.jdbc.JDBC4Connection@591ac8
如果我们在获取是,在 id 前加上“&”符号,那么获取的将不再是复杂对象,而是 ConnectionFactoryBean 对象
@Test
public void t4() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring.xml");
ConnectionFactoryBean conn = (ConnectionFactoryBean) context.getBean("&conn");
System.out.println(conn);
}
factorybean.ConnectionFactoryBean@18edcc5
如果对象能够被公用,就设置为单例,即返回 true ,否则设置为多例,返回false,jdbc 的 Connection 对象在事务处理时,明显不可以公用,因此使用多例比较合适,而 MyBatis 的 SqlSessionFactory 是重量级的对象,因此使用单例更为合适,其他对象可以根据上述原则配置即可。
由于mysql版本问题,你可能会遇到报错说没有使用ssl证书,因为mysql为了保证更加安全,添加了ssl证书验证,当然我们是没有的哈,只需要在url上配置一下就不在提示了。
useSSL=false
jdbc:mysql://localhost:3306/zhou?useSSL=false
ConnectionFactoryBean中用户名,密码,url等等参数直接通过字符串的形式写在了程序里,使用了硬编码,耦合了,我们使用依赖注入来解决这块的耦合。
依赖这几个字符串,就把他们声明为成员变量,并提供set方法
package factorybean;
import org.springframework.beans.factory.FactoryBean;
import java.sql.Connection;
import java.sql.DriverManager;
public class ConnectionFactoryBean implements FactoryBean<Connection> {
private String driverClassName;
private String url;
private String username;
private String password;
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
// 写创建复杂对象的代码
@Override
public Connection getObject() throws Exception {
Class.forName(driverClassName);
return DriverManager.getConnection(url, username, password);
}
// 返回创建对象的Class对象
@Override
public Class<?> getObjectType() {
return Connection.class;
}
// 是否为单例
@Override
public boolean isSingleton() {
return true;
}
}
在Spring配置文件中完成注入
<bean id="conn" class="factorybean.ConnectionFactoryBean">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/zhou?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
bean>
再次测试
@Test
public void t3() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring.xml");
Connection conn = (Connection) context.getBean("conn");
System.out.println(conn);
}
没有任何问题
com.mysql.jdbc.JDBC4Connection@13f604a
就这样,轻松的解决了耦合问题,这就是Spring。
FactoryBean 的实现类目的: 避免Spring框架的侵入,整合遗留系统
ConnectionFactory
package factorybean;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectionFactory {
public Connection getConnection() {
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/zhou?useSSL=false", "root", "root");
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return conn;
}
}
spring.xml
<bean id="connectionFactory" class="factorybean.ConnectionFactory"/>
<bean id="con" factory-bean="connectionFactory" factory-method="getConnection"/>
test
@Test
public void t5() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring.xml");
Connection conn = (Connection) context.getBean("con");
System.out.println(conn);
}
com.mysql.jdbc.JDBC4Connection@fcf36f
StaticConnectionFactory
public class StaticConnectionFactory {
public static Connection getConnection() {
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/zhou?useSSL=false", "root", "root");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
}
spring.xml
<bean id="conn" class="factorybean.StaticConnectionFactory" factory-method="getConnection"/>
test
@Test
public void t3() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring.xml");
Connection conn = (Connection) context.getBean("conn");
System.out.println(conn);
}
com.mysql.jdbc.JDBC4Connection@1aab8c6

座右铭:不要在乎别人如何看你,要在乎你自己如何看未来,看梦想,看世界…!
一起学习的可以私信博主或添加博主微信哦。