经过测试对于具体的一个Bean,执行的流程应该是:
1.实例化:
常见的有构造(有参、无参)实例化、静态工厂(方法是静态,通过类名.方法返回获取)、实例工厂(专门有个类负责生产对象,需要在bean中配置类和方法名~非静态)
2.注入
注入有3种(set注入、构造注入、接口注入),如果有注入,则实例化注入对象,注入对象优先完成以下步骤,再注入,再完成bean类的以下步骤。没有注入直接完成下面步骤。
3.传id至方法
如果当前bean类有实现BeanNameAware接口,并重写setBeanName()方法,先执行此方法。
4.传BeanFactory工厂至方法
如果当前bean类实现BeanFactoryAware接口,并重写setBeanFactroy()方法,再执行此方法。
5.传ApplicationContext容器至方法
如果当前bean类实现AapplicationContextAware接口,并重写setApplicationContext()方法,再执行此方法。
6.BeanPostProcessor处理器进行前后预处理
另外如果存在bean类实现BeanPostProcessor接口,并重写postProcessBeforeInitialization和postProcessAfterInitialization方法。程序会先执行Before(同左)方法再执行init()方法,最后执行After(同左)方法。注意:每个对象实例化过程都会调用此方法。可以用传递的对象对对象内容进行更改。好东西啊。
7.使用代理管理事物(目标方法前打开事物,目标方法后关闭事物)
在postProcessAfterInitialization方法的返回中使用代理返回。代码如下:
@Override public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException { System.out.println("后"+beanName); return Proxy.newProxyInstance(MyBeanProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("-----开启事物-------"); //执行模板方法 Object obj = method.invoke(bean, args); System.out.println("--------提交事物--------"); return obj; } }); }
8.destroy()方法
此方法可以在bean中进行声明,也可以通过bean类实现DisposableBean接口,重写destroy方法(),执行销毁bean。
小结:程序运行结果:
实现代码:
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!-- 此类实现BeanPostProcessor接口 --> <bean class="com.xx.service.MyBeanProcessor"/> <!-- service --> <bean id="userService" class="com.xx.service.UserServiceImpl" init-method="init" destroy-method="destroy" scope="singleton"> <property name="userDao" ref="userDao"/> </bean> <!-- dao --> <bean id="userDao" class="com.xx.dao.UserDaoImpl"/> </beans>
service层接口:
package com.xx.service; public interface UserService { public void run(); }
Service层实现类:
package com.xx.service; 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.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import com.xx.dao.UserDao; /** * userService层实现类 * @author phoebe * */ public class UserServiceImpl implements UserService,BeanNameAware,BeanFactoryAware,ApplicationContextAware,DisposableBean{ private UserDao userDao; public void setUserDao(UserDao userDao) { System.out.println("注入dao"); this.userDao = userDao; } public UserServiceImpl() { System.out.println("实例化Service"); } //目标方法 public void run(){ System.out.println("userService is running"); } //测试方法 public void testBeanFactoryAware(){ System.out.println("证明bean对象被传送过来了"); } //初始方法 public void init(){ System.out.println("this is init method"); } //销毁方法 public void destroy(){ System.out.println("this is destroy method"); } @Override public void setBeanName(String name) { System.out.println("BeanNameAware:"+name); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("BeanFactoryAware:"+beanFactory.containsBean("userService")); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("ApplicationContextAware:"+applicationContext.containsBean("userService"));; } }
Dao层接口:
package com.xx.dao; public interface UserDao { //测试方法 public void testDao(); }
Dao层实现类:
package com.xx.dao; public class UserDaoImpl implements UserDao{ public UserDaoImpl() { System.out.println("实例化Dao"); } @Override public void testDao() { System.out.println("Dao is running"); } }
处理器进行前后预处理
package com.xx.service; 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; /** * 处理器进行前后预处理 * @author phoebe * */ public class MyBeanProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("init前:"+beanName); return bean; } @Override public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException { System.out.println("init后"+beanName); return Proxy.newProxyInstance(MyBeanProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("-----目标方法前:开启事物-------"); //执行模板方法 Object obj = method.invoke(bean, args); System.out.println("--------目标方法后:提交事物--------"); return obj; } }); } }
测试:
package com.xx.test; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.xx.service.UserService; /** * spring生命周期测试 * @author phoebe * */ public class UserServiceTest { private ApplicationContext context = null; @Before public void before(){ String beanPath="classpath:applicationContext.xml"; context = new ClassPathXmlApplicationContext(beanPath); } @Test public void TestApp() throws Exception { UserService userService = context.getBean("userService",UserService.class); userService.run(); context.getClass().getMethod("close").invoke(context); } }
Best Regards