一、前言
1、Spring框架运用了非常多的设计模式,从整体上看,它的设计严格遵循了OCP---开闭原则,即
【1】保证对修改关闭,即外部无法修改Spring整个运作的流程
【2】提供对扩展开放,即可以通过继承、实现Spring提供的众多抽象类与接口来改变类加载的行为
二、BeanNameAware、ApplicationContextAware和BeanFactoryAware
1、实现BeanNameAware接口,在加载过程中可以获取到该Bean的ID
2、实现ApplicationContextAware接口,在加载过程中可以获取到ApplicationContext上下文
3、实现BeanFactroyAware接口,在加载过程中可以获取到该Bean的BeanFactory
package XXX;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.InitializingBean;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Service;//aware:可感知到的@Servicepublic class BeanTest implements BeanNameAware, ApplicationContextAware,BeanFactoryAware,InitializingBean {private static String beanName;private static ApplicationContext applicationContext;private static ApplicationContext parentApplicationContext;private static BeanFactory beanFactory;/*** 执行顺序:1*/@Overridepublic void setBeanName(String name) {System.out.println("setBeanName(...)");//当前Bean的名称"BeanTest"this.beanName = name;}/*** 执行顺序:2*/@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("setBeanFactory(...)");this.beanFactory = beanFactory;}/*** 执行顺序:3*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext)throws BeansException {System.out.println("setApplicationContext(...)");this.applicationContext = applicationContext;this.parentApplicationContext = applicationContext.getParent();}/*** 执行顺序:4*/@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("afterPropertiesSet()");}}
三、InitialingBean和DisposableBean -- 举例ExtConsumerConfig
1、initialingBean是一个接口,提供了唯一的方法afterpropertiesSet()
2、DisposibleBean也是一个接口,提供了唯一的方法destory()
【1】执行顺序:接口优先于配置,即
initialingBean>init-method;
DisposibleBean>destroy-method
【2】执行机制:
initialingBean和
DisposibleBean底层使用类型强转.方法名()进行直接调用;
init-method和
destroy-method使用反射
package XX;import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.InitializingBean;import org.springframework.stereotype.Service;@Servicepublic class InitialingBeanAndDisposableBeanTest implements InitializingBean,DisposableBean {private Integer age;public void setAge(Integer age) {this.age = age;System.out.println("setAge()");//如果在XML中配置了property}@Overridepublic void destroy() throws Exception {System.out.println("desrroy()");}/*** 当前Bean(InitialingBeanAndDisposableBeanTest)的所有属性设置完成后调用*/@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("afterPropertiesSet()");}//以上打印顺序:setAge()->afterPropertiesSet()->destroy()}
四、FactoryBean
1、传统Spring容器加载一个Bean的整个过程都是由Spring控制的,开发者除了设置Bean的相关属性外,没有太多自主权
2、FactoryBean改变了这一点,开发者可以个性化的定制自己想要实例化出来的Bean
IAnimal接口:
public interface Animal {public abstract void say();}
Cat实现类:
public class Cat implements Animal {@Overridepublic void say() {System.out.println("cat.say()");}}
Dog实现类:
public class Dog implements Animal {@Overridepublic void say() {System.out.println("Dog.say()");}}
FactoryBean实现类:
package XXX;import org.springframework.beans.factory.FactoryBean;@Servicepublic class FactoryBeanTest implements FactoryBean<Animal> {private static String name = "cat"; // 可以在xml中配置@Overridepublic Animal getObject() throws Exception {if("cat".equals(name)){return new Cat();}else if ("dog".equals(name)) {return new Dog();}return null;}@Overridepublic Class<?> getObjectType() {return Animal.class;}@Overridepublic boolean isSingleton() {return true;// 返回单例}}
JunitTest(XML中配置省略,把
FactoryBeanTest配置到Bean即可 || 或者用@Service注解
):
package XX;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class JunitTest {@Testpublic void test() {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("config/spring/beans.xml");//此处得到的是XX.Cat@57c39581,可见得到了具体的实现类Object object = applicationContext.getBean("factoryTest");Animal animal = (Animal) object;// 结果为:Cat.say()animal.say();}}
五、BeanPostProcessor -- 举例:AnnotationBeanProcessor
1、之前的initializinngBean、DisposableBean、init-method、destroy-method、FactoryBean都是针对
单个Bean控制其初始化的操作
2、BeanPostProcessor则可以针对
每个(所有Bean加载前后都会调下面方法)Bean生成前后执行一些逻辑;有两个接口:
【1】postProcessorBeforeInitializing:在初始化Bean之前执行
【2】postProcessorAfterInitializing:在初始化Bean之后执行
3、
单个Bean生命周期如下(从下面打印日志可以看出BeanTest类的执行顺序):
package XX;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanPostProcessor;import org.springframework.stereotype.Service;@Servicepublic class BeanPostProcessorTest implements BeanPostProcessor{/*** 每个Bean的生成前都会调用*/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException {System.out.println("BeanPostProcessorTest.postProcessBeforeInitialization()");return bean;}/*** 每个Bean生成过程中,如果有Bean实现自InitializingBean或者配置了init-method方法,会执行*//*** 每个Bean生成后都会调用*/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName)throws BeansException {System.out.println("BeanPostProcessorTest.postProcessAfterInitialization()");return bean;}}
六、BeanFactoryPostProcessor
1、实现自BeanFactoryPostProcessor,即可以在Spring创建Bean之前,读取Bean的元属性,并根据需要对元属性进行修改,比如将Bean的scope从singleton改变为prototype
2、BeanFactoryPostProcessor的优先级
高于BeanPostProcessor
3、BeanFactoryPostProcessor的postProcessorBeanFactory()方法只会执行
一次
package XX;import org.springframework.beans.BeansException;import org.springframework.beans.MutablePropertyValues;import org.springframework.beans.factory.config.BeanDefinition;import org.springframework.beans.factory.config.BeanFactoryPostProcessor;import org.springframework.beans.factory.config.ConfigurableBeanFactory;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.stereotype.Service;@Servicepublic class BeanFactoryPostProcessorTest implements BeanFactoryPostProcessor {/*** 获取Bean元属性并修改等操作*/@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("postProcessBeanFactory(...)");//修改元属性scopeBeanDefinition beanDefinition = beanFactory.getBeanDefinition("systemParamInit");System.out.println("scope for systemParamInit before : " + beanDefinition.getScope());beanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);System.out.println("scope for systemParamInit after : " + beanDefinition.getScope());//获取Bean的属性参数并打印MutablePropertyValues mutablePropertyValues = beanDefinition.getPropertyValues();System.out.println("systemParamInit properties :" + mutablePropertyValues);}}
七、InstantiationAwareBeanPostProcessor
1、InstantiationAwareBeanPostProcessor又代表了另外一个Bean的生命周期:
实例化
2、实例化 --- 实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中
初始化 --- 初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性
3、之前的BeanPostProcessor作用于2过程,现在这个类则作用于1过程
package XX;import java.beans.PropertyDescriptor;import org.springframework.beans.BeansException;import org.springframework.beans.PropertyValues;import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;import org.springframework.stereotype.Service;@Servicepublic class InstantiationAwareBeanPostProcessorTest implements InstantiationAwareBeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("InstantiationAwareBeanPostProcessorTest.postProcessBeforeInitialization()");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("InstantiationAwareBeanPostProcessorTest.postProcessAfterInitialization()");return bean;}@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {System.out.println("InstantiationAwareBeanPostProcessorTest.postProcessBeforeInstantiation()");return beanClass;}@Overridepublic boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {System.out.println("InstantiationAwareBeanPostProcessorTest.postProcessAfterInstantiation()");return true;}@Overridepublic PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {return pvs;}}