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:可感知到的@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;}}
1 0
- Spring Bean常用扩展接口
- Spring:一些常用的Spring Bean扩展接口
- Spring8:一些常用的Spring Bean扩展接口
- Spring8:一些常用的Spring Bean扩展接口
- Spring生命周期中常用的Bean扩展接口
- Spring Bean扩展接口 -- ApplicationContextAware源码分析
- Spring Bean扩展接口 -- InitializingBean源码分析
- spring常用的几个aware bean接口:
- Spring Bean--Aware接口
- 深入理解Spring系列之八:常用的扩展接口
- spring常用的bean写法
- 【Spring】Spring常用配置-Bean的Scope
- Spring 常用接口说明
- 【原创】Spring-Bean接口的初始化...
- spring配置事物bean必须配接口
- Spring入门 Bean装配之Aware接口
- Spring中与Bean相关的接口
- Spring入门(Bean的Aware接口)
- 【数据结构】广义表
- KISSY基础篇乄KISSY之Seed
- hashcode方法
- NOIP2016普及组复赛全国一等奖名单及排名(1~745名)
- 在Ubuntu16.04中配置Anaconda(Python2.7)以支持Spark2.0(Pyspark)
- Spring Bean常用扩展接口
- 16G内存显示15.9G可用的解法
- [BZOJ2653]middle(二分+主席树)
- c程序
- IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter notifyItemRangeRemove
- C++ 菱形继承问题 虚继承和虚基类
- 在Fedora 25中更换openjdk为oracle jdk
- Codeforces 667C Reberland Linguistics dp+set
- 1.Two Sum