Spring再次学习(4)
时隔一年多,在掌握了spring、springboot、springcloud之后
我再次回头,重新学习spring框架
bean的生命周期学习:
在传统的xml配置中,可以这样自定义初始化和销毁方法:
init-method="" destroy-method=""
注解方式的简单使用:
@configuration
public class lifecircleconfig {
@bean(initmethod = "init",destroymethod = "destroy")
public car car(){
return new car();
}
}
public class car {
public car(){
system.out.println("construct car!");
}
public void init(){
system.out.println("car init!");
}
public void destroy(){
system.out.println("car destroy!");
}
}
public class lifecircletest {
private static annotationconfigapplicationcontext applicationcontext = new annotationconfigapplicationcontext(lifecircleconfig.class);
@test
public void test(){
applicationcontext.close();
}
}
注意:要有close方法,否则不会打印car销毁方法
打印如下:
construct car! car init! car destroy!
这里默认的是单实例bean
如果是多实例的话,按照以上的测试代码是不会打印的,因为多实例情况下,在获取bean的情况下才会创建对象
而且在多例情况下,只会调用初始化和构造方法,不会调用销毁方法
以上测试代码只完成了初始化ioc容器,所以什么都不打印
实现spring中接口方式:这时候不需要在@bean中进行配置
public class car implements initializingbean, disposablebean {
public car() {
system.out.println("construct car!");
}
public void afterpropertiesset() throws exception {
system.out.println("car init!");
}
public void destroy() {
system.out.println("car destroy!");
}
}
使用java原生注解:
public class car {
public car() {
system.out.println("construct car!");
}
@postconstruct
public void init() {
system.out.println("car init!");
}
@predestroy
public void destroy() {
system.out.println("car destroy!");
}
}
使用spring中bean的后置处理器:
@component
public class mybeanpostprocessor implements beanpostprocessor {
/**
* 初始化前调用
*/
public object postprocessbeforeinitialization(object bean, string beanname) throws beansexception {
system.out.println("postprocessbeforeinitialization " + bean + " " + beanname);
return bean;
}
/**
* 初始化后调用
*/
public object postprocessafterinitialization(object bean, string beanname) throws beansexception {
system.out.println("postprocessafterinitialization " + bean + " " + beanname);
return bean;
}
}
@configuration
@componentscan("org.dreamtech.bean")
public class lifecircleconfig {
@bean
public car car(){
return new car();
}
}
测试后部分打印如下:
construct car! postprocessbeforeinitialization org.dreamtech.bean.car@2d9d4f9d car postprocessafterinitialization org.dreamtech.bean.car@2d9d4f9d car
beanpostprocessor原理:
查看这一段源码:
initializebean(beanname, exposedobject, mbd)方法中:
object wrappedbean = bean;
if (mbd == null || !mbd.issynthetic()) {
wrappedbean = applybeanpostprocessorsbeforeinitialization(wrappedbean, beanname);
}
try {
invokeinitmethods(beanname, wrappedbean, mbd);
}
catch (throwable ex) {
throw new beancreationexception(
(mbd != null ? mbd.getresourcedescription() : null),
beanname, "invocation of init method failed", ex);
}
if (mbd == null || !mbd.issynthetic()) {
wrappedbean = applybeanpostprocessorsafterinitialization(wrappedbean, beanname);
}
在invokeinitmethods初始化方法之前
调用了applybeanpostprocessorsbeforeinitialization,也就是调用了所有postprocessor的before方法
在invokeinitmethods初始化方法之后
调用了applybeanpostprocessorsafterinitialization,也就是调用了所有postprocessor的after方法
进入applybeanpostprocessorsbeforeinitialization方法查看源码:
遍历所有的processor,一旦返回null,就会跳出循环
@override
public object applybeanpostprocessorsbeforeinitialization(object existingbean, string beanname)
throws beansexception {
object result = existingbean;
for (beanpostprocessor beanprocessor : getbeanpostprocessors()) {
result = beanprocessor.postprocessbeforeinitialization(result, beanname);
if (result == null) {
return result;
}
}
return result;
}
在initializebean方法之前,调用的是populatebean方法
作用:给属性赋值
// initialize the bean instance.
object exposedobject = bean;
try {
populatebean(beanname, mbd, instancewrapper);
if (exposedobject != null) {
exposedobject = initializebean(beanname, exposedobject, mbd);
}
}
所以:beanpostprocessor是在bean赋值之后,初始化的过程前后执行的
beanpostprocessor在spring底层的使用:
获取ioc容器的接口:
public interface applicationcontextaware extends aware {
void setapplicationcontext(applicationcontext var1) throws beansexception;
}
而它就是基于beanpostprocessor的,代码过长就不截取了
class applicationcontextawareprocessor implements beanpostprocessor
或者是参数校验:也使用到了beanpostprocessor
public class beanvalidationpostprocessor implements beanpostprocessor, initializingbean
部分代码如下:
public object postprocessbeforeinitialization(object bean, string beanname) throws beansexception {
if (!this.afterinitialization) {
this.dovalidate(bean);
}
return bean;
}
public object postprocessafterinitialization(object bean, string beanname) throws beansexception {
if (this.afterinitialization) {
this.dovalidate(bean);
}
return bean;
}