Spring Bean常用扩展接口

来源:互联网 发布:java xml解析 编辑:程序博客网 时间:2024/06/05 17:10

一、前言

    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:可感知到的
@Service
public class BeanTest implements BeanNameAware, ApplicationContextAware,
        BeanFactoryAware,InitializingBean {
    private static String beanName;
    private static ApplicationContext applicationContext;
    private static ApplicationContext parentApplicationContext;
    private static BeanFactory beanFactory;
    /**
     * 执行顺序:1
     */
    @Override
    public void setBeanName(String name) {
        System.out.println("setBeanName(...)");//当前Bean的名称"BeanTest"
        this.beanName = name;
    }
    
    /**
     * 执行顺序:2
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("setBeanFactory(...)");
        this.beanFactory = beanFactory;
    }
    /**
     * 执行顺序:3
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        System.out.println("setApplicationContext(...)");
        this.applicationContext = applicationContext;
        this.parentApplicationContext = applicationContext.getParent();
    }
    /**
     * 执行顺序:4
     */
    @Override
    public 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;
@Service
public class InitialingBeanAndDisposableBeanTest implements InitializingBean,
        DisposableBean {
    private Integer age;
    public void setAge(Integer age) {
        this.age = age;
        System.out.println("setAge()");//如果在XML中配置了property
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("desrroy()");
    }
    /**
     * 当前Bean(InitialingBeanAndDisposableBeanTest)的所有属性设置完成后调用
     */
    @Override
    public 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 {
    @Override
    public void say() {
        System.out.println("cat.say()");
    }
}
      Dog实现类:
public class Dog implements Animal {
    @Override
    public void say() {
        System.out.println("Dog.say()");
    }
}

   FactoryBean实现类:
package XXX;
import org.springframework.beans.factory.FactoryBean;
@Service
public class FactoryBeanTest implements FactoryBean<Animal> {
    private static String name = "cat"// 可以在xml中配置
    @Override
    public Animal getObject() throws Exception {
        if("cat".equals(name)){
            return new Cat();
        }else if ("dog".equals(name)) {
            return new Dog();
        }
        return null;
    }
    @Override
    public Class<?> getObjectType() {
        return Animal.class;
    }
    @Override
    public 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 {
    @Test
    public 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;
@Service
public class BeanPostProcessorTest implements BeanPostProcessor{
    /**
     * 每个Bean的生成前都会调用
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println("BeanPostProcessorTest.postProcessBeforeInitialization()");
        return bean;
    }
    
    /**
     * 每个Bean生成过程中,如果有Bean实现自InitializingBean或者配置了init-method方法,会执行
     */
    /**
     * 每个Bean生成后都会调用
     */
    @Override
    public 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;
@Service
public class BeanFactoryPostProcessorTest implements BeanFactoryPostProcessor {
    /**
     * 获取Bean元属性并修改等操作
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("postProcessBeanFactory(...)");
        
        //修改元属性scope
        BeanDefinition 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;
@Service
public class InstantiationAwareBeanPostProcessorTest implements InstantiationAwareBeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessorTest.postProcessBeforeInitialization()");
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessorTest.postProcessAfterInitialization()");
        return bean;
    }
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessorTest.postProcessBeforeInstantiation()");
        return beanClass;
    }
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessorTest.postProcessAfterInstantiation()");
        return true;
    }
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        return pvs;
    }
}


1 0
原创粉丝点击