【Spring】bean元素的生命周期

默认的生命周期为

-bean的生命周期
    -1 调用无参构造,实例化
    -2 调用参数的setter,为属性注入值
    -3 (可选)如果bean实现了BeanNameAware接口,则会执行接口方法setBeanAname(String beanid),bean可以获取其在容器中的id
    -4 (可选)如果bean实现了BeanFactoryAware接口,则会执行接口方法setBeanFactory(BeanFactory factory),Bean可以获取到BeanFactory对象
    -5 (可选)如果定义了bean后处理器,执行 postProcessBeforeInitialization()
    -6 (可选)如果bean实现了InitializingBean接口,则执行接口方法afterPropertiesSet(),这个方法在Bean的所有属性的set方法执行完毕后执行,是Bean初始化结束的标志(重要)
    -7 (可选)如果设置了init-method方法,则执行
    -8 (可选)如果定义了bean后处理器,执行 postProcessAfterInitialization()
    -9  执行业务方法
    -10 (可选)如果bean实现了DisposableBean接口,则执行接口方法destroy()

    -11 (可选)如果设置了destroy-method方法,则执行

代码验证:

1. 定义IService接口

package beanAssemble.ba07;

public interface IService {
	void doSome();
	void doOther();
	void setUp();
	void tearDown();
}

2. 定义StudentServiceImpl实体类实现接口

package beanAssemble.ba07;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

/**
 * 待增强的Bean类
 * @author copywang
 *
 */
public class StudentServiceImpl implements IService,BeanNameAware,BeanFactoryAware,InitializingBean,DisposableBean{
	private String name;
	public StudentServiceImpl() {
		System.out.println("getBean()首先调用的是无参构造");
	}

	@Override
	public void doSome() {
		System.out.println(this.getClass().getSimpleName() + "doSome() 真实业务");
	}

	@Override
	public void doOther() {
		System.out.println(this.getClass().getSimpleName() + "doOther()");
	}

	@Override
	public void setBeanName(String beanName) {
		// TODO Auto-generated method stub
		System.out.println("BeanNameAware接口的setBeanName()" + "可以获得在XML中配置的Bean ID 是" + beanName);
	}

	@Override
	public void destroy() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("DisposableBean接口的destroy()");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("InitializingBean接口的afterPropertiesSet() 对象已经初始化完毕了!");
	}

	@Override
	public void setBeanFactory(BeanFactory bf) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("BeanFactoryAware接口的setBeanFactory()" + "可以获得BeanFactory的对象是:" + bf);
	}
	public void setUp() {
		System.out.println("init-method xml中的创建后行为");
		
	}
	public void tearDown() {
		System.out.println("destroy-method xml的销毁前行为");
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		System.out.println("为name属性注入值");
		this.name = name;
	}
}

3. 定义MyBeanPostProcessor后处理器类

package beanAssemble.ba07;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPostProcessor implements BeanPostProcessor {
	/**
	 * @param arg0 系统即将初始化的Bean实例
	 * @param arg1 Bean实例的ID属性值(或者name)
	 */
	@Override
	public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException {
		//即使不对Bean进行增强,也要返回Bean,不能为null
		System.out.println("BeanPostProcessor接口的postProcessAfterInitialization()方法");
		return arg0;
	}
	/**
	 * 对StudentServiceImpl进行增强
	 * @param arg0 系统即将初始化的Bean实例
	 * @param arg1 Bean实例的ID属性值(或者name)
	 */
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		//反射
		if (bean instanceof StudentServiceImpl) {
			//proxy就是动态代理生成的一个队指定接口的实现类对象,可以直接调用实现类的方法proxy.xxx()
			//newProxyInstance(classLoader,intefaces,InvocationHandler())
			//第1个参数,实现类的类加载器
			//第2个参数,实现类所实现的接口
			//第3个参数,InvocationHandler()接口,调用处理器
			/*
			 * 只有1个方法invoke()
			 * Object proxy:代理对象,也就是Proxy.newProxyInstance()方法返回的对象
			 * Method method:表示当前被调用方法的反射对象,例如proxy.some(),那么method就是some()方法的反射对象
			 * Object[] args:表示当前被调用方法的参数
			 * invoke()方法的返回值为Object类型,它表示当前被调用的方法的返回值,没有返回值的话,就是返回null
			*/
			/* ===================================================================================
			 * public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
							return result;
						}
			 * ===================================================================================
			 * 
			 * ===================================================================================
			 * Object result = proxy.method(args)
			 * ===================================================================================
			 * 
			 * 上面这两段代码的对应
			 * result -> result
			 * proxy -> proxy
			 * method -> method
			 * args -> args
			 * 
			 * ===================================================================================
			 * 无论调用代理对象上的哪个方法,其实都是在调用InvocationHandler的invoke()方法
			 * 所以invoke()返回的就是method.invoke(bean,args)
			 */
			Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), 
					bean.getClass().getInterfaces(), 
					new InvocationHandler() {

						@Override
						public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
							if ("doSome".equals(method.getName())) {
								System.out.println("BeanPostProcessor接口的方法增强,下一步调用业务");
								//执行目标方法doSome()
								Object invoke = method.invoke(bean, args);
								return invoke;
							}
							return method.invoke(bean, args);
						}
			});
			return proxy;
		}
		return bean;
	}
}

4. 配置application.xml文件




    
    
    
	
    
	
		
	
	
	

5. 编写TestDemo测试类

package beanAssemble.ba07;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestDemo {

	@Test
	public void test() {
		ApplicationContext ac = new ClassPathXmlApplicationContext("beanAssemble/application-ba07.xml");
		// 从容器获取Service
		IService studentService = (IService) ac.getBean("studentService");
		studentService.doSome();
		((ClassPathXmlApplicationContext) ac).close();
	}
}

6. 输出结果

getBean()首先调用的是无参构造
为name属性注入值
BeanNameAware接口的setBeanName()可以获得在XML中配置的Bean ID 是studentService
BeanFactoryAware接口的setBeanFactory()可以获得BeanFactory的对象是:org.springframework.beans.factory.support.DefaultListableBeanFactory@59ec2012: defining beans [beanProcessor,studentService,teacherService]; root of factory hierarchy
InitializingBean接口的afterPropertiesSet() 对象已经初始化完毕了!
init-method xml中的创建后行为
BeanPostProcessor接口的postProcessAfterInitialization()方法
BeanPostProcessor接口的postProcessAfterInitialization()方法
BeanPostProcessor接口的方法增强,下一步调用业务
StudentServiceImpldoSome() 真实业务
DisposableBean接口的destroy()
destroy-method xml的销毁前行为

加深一下对bean生命周期的理解



你可能感兴趣的:(Spring)