Spring 工厂何时创建对象?‘
什么时候? Spring 工厂在创建完对象后,调用对象的初始化方法,完成对应的初始化操作。 初始化方法提供:程序员根据需求,提供初始化方法,最终完成初始化操作。 初始化方法调用:Spring 工厂进行调用。
提供初始化方法的两种方式:
InitializingBean 接口:
public class Product implements InitializingBean { //程序员根据需求实现的方法, 完成初始化操作 @Override public void afterPropertiesSet() throws Exception { System.out.println("Product.afterPropertiesSet"); } }
对象中提供一个普通的初始化方法,配置文件种配置 init-method:
public class Product { public void myInit() { System.out.println("Product.myInit"); } }
<bean id="product" class="com.yusael.life.Product" init-method="myInit"/>
Spring 销毁对象前,会调用对象的销毁方法,完成销毁操作。
销毁方法调用:Spring 工厂进行调用。
开发流程与初始化操作一样,提供销毁方法的两种方式:
DisposableBean 接口:
public class Product implements DisposableBean { // 程序员根据⾃⼰的需求, 定义销毁方法, 完成销毁操作 @Override public void destroy() throws Exception { System.out.println("Product.destroy"); } }
对象中提供一个普通的销毁方法,配置文件种配置 destroy-method:
public class Product { // 程序员根据⾃⼰的需求, 定义销毁方法, 完成销毁操作 public void myDestory() { System.out.println("Product.myDestory"); } }
<bean id="product" class="com.yusael.life.Product" destroy-method="myDestory"/>
public class Product implements InitializingBean, DisposableBean { private String name; public String getName() { return name; } public void setName(String name) { System.out.println("Product.setName"); this.name = name; } Product() { // 创建 System.out.println("Product.Product"); } // 程序员根据需求实现的方法, 完成初始化操作 public void myInit() { System.out.println("Product.myInit"); } // 程序员根据需求实现的方法, 完成初始化操作 @Override public void afterPropertiesSet() throws Exception { System.out.println("Product.afterPropertiesSet"); } public void myDestory() { System.out.println("Product.myDestory"); } // 程序员根据⾃⼰的需求, 定义销毁方法, 完成销毁操作 @Override public void destroy() throws Exception { System.out.println("Product.destroy"); } }
<bean id="product" class="com.yusael.life.Product" init-method="myInit" destroy-method="myDestory"> <property name="name" value="yusael"/> </bean>
img1
配置文件参数化:把 Spring 配置文件中需要经常修改的字符串信息,转移到?个更小的配置文件中。
优点:利于 Spring 配置文件的维护(修改)
提供?个小的配置文件(.properities) 名字:没有要求 放置位置:没有要求
jdbc.driverClassName = com.mysql.jdbc.Driver jdbc.url = jdbc:mysql://localhost:3306/spring?useSSL=false jdbc.username = root jdbc.password = 1234
Spring 的配置文件与小配置文件进行整合:
<!--Spring的配置文件与⼩配置文件进行整合--> <!--resources 下的文件在整个程序编译完后会被放到 classpath 目录下,src.main.java中的文件也是--> <context:property-placeholder location="classpath:/db.properties"/>
在 Spring 配置文件中通过 ${key} 获取小配置文件中对应的值:
<bean id="conn" class="com.yusael.factorybean.ConnectionFactoryBean"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>
产生原因:当 Spring 内部没有提供特定类型转换器时,而程序员在应用的过程中还需要使用,那么 就需要程序员??定义类型转换器。
类 implements Converter 接口
public class MyDateConverter implements Converter<String, Date> { /* convert方法作用: String ---> Date SimpleDateFormat sdf = new SimpleDateFormat(); sdf.parset(String) ---> Date 参数: source : 代表的是配置文件中, 日期字符串 <value>2020-10-11</value> return : 当把转换好的 Date 作为 convert 方法的返回值后, Spring ⾃动的为birthday属性进行注入(赋值) */ @Override public Date convert(String source) { Date date = null; try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); date = sdf.parse(source); } catch (ParseException e) { e.printStackTrace(); } return date; } }
在 Spring 的配置文件中进行配置; 先创建 MyDateConverter 对象,再注册类型转换器;
<!--创建 MyDateConverter 对象--> <bean id="myDateConverter" class="com.yusael.converter.MyDateConverter"/> <!--用于注册类型转换器--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <ref bean="myDateConverter"/> </set> </property> </bean> <bean id="good" class="com.yusael.converter.Good"> <property name="name" value="zhenyu"/> <property name="birthday" value="2012-12-12"/> </bean>
MyDateConverter 中的日期的格式,通过 依赖注入 的方式,由配置文件完成赋值。
public class MyDateConverter implements Converter<String, Date> { private String pattern; @Override public Date convert(String source) { Date date = null; try { SimpleDateFormat sdf = new SimpleDateFormat(pattern); date = sdf.parse(source); } catch (ParseException e) { e.printStackTrace(); } return date; } public String getPattern() { return pattern; } public void setPattern(String pattern) { this.pattern = pattern; } }
<!-- 配置文件完成对日期格式的赋值 --> <bean id="myDateConverter" class="com.yusael.converter.MyDateConverter"> <property name="pattern" value="yyyy-MM-dd"/> </bean>
ConversionSeviceFactoryBean 定义 id属性,值必须是 conversionService;
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <ref bean="myDateConverter"/> </set> </property> </bean>
Spring 框架其实内置了日期类型的转换器:日期格式必须是 2020/05/01。
<bean id="good" class="com.yusael.converter.Good"> <property name="name" value="zhenyu"/> <property name="birthday" value="2012/12/12"/> </bean>
BeanPostProcessor 作用:对 Spring 工厂所创建的对象,进行再加工。(AOP 的底层实现)
img2
postProcessBeforeInitialization 作用:Spring 创建完对象,并进行注入后,可以运行 Before ?法进行加工; 通过方法的参数获得 Spring 创建好的对象,最终通过返回值交给 Spring 框架。
public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; }
postProcessAfterInitialization 作?:Spring 执行完对象的初始化操作后,可以运行 After ?法进行加工; 通过方法的参数获得 Spring 创建好的对象,最终通过返回值交给 Spring 框架。
public Object postProcessAfterInitialization(Object bean, String beanName) { return bean; }
类 实现 BeanPostProcessor 接口
public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return null; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { Category category = (Category) bean; category.setName("yusael"); return category; } }
Spring 配置文件中进行配置
<bean id="myBeanPostProcessor" class="com.yusael.beanpost.MyBeanPostProcessor"/>
细节 BeanPostProcessor 会对 Spring 工厂创建的所有对象进行加工。如果工厂创建了多个不同的对象,要注意区别传入的对象:
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Category) { Category category = (Category) bean; category.setName("yusael"); return category; } return bean; }
原文:https://www.cnblogs.com/instinct-em/p/13381175.html