zoukankan      html  css  js  c++  java
  • spring(三):spring中BeanPostProcessor的使用

    spring中实现BeanPostProcessor的后置处理器

    ApplicationContextAwareProcessor

    进入该实现类内部

    可以看到:该类帮我们组建IOC容器,判断我们的bean有没有实现ApplicationContextAware接口,并作出相应处理(setApplicationContext方法)

    测试:调试一个实现ApplicationContextAware接口的类的创建过程

    public class User implements ApplicationContextAware {
        private ApplicationContext applicationContext;
    
        public User(){
            System.out.println("User...constructor....");
        }
    
        @PostConstruct
        public void init(){
            System.out.println("User...init....");
        }
    
        @PreDestroy
        public void destroy(){
            System.out.println("User...destroy....");
        }
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            /**
             * 容器初始化,将applicationContext作为参数传入,其它方法就可以使用容器了
             * 该方法是由ApplicationContextAwareProcessor处理器来执行的
             */
            this.applicationContext = applicationContext;
        }
    }
    

    在ApplicationContextAwareProcessor类的postProcessBeforeInitialization方法中添加断点

    public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    	AccessControlContext acc = null;
    	if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || 
    		bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware 
    		|| bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware 
    		|| bean instanceof ApplicationContextAware)) {//1
    		acc = this.applicationContext.getBeanFactory().getAccessControlContext();
    	}
    
    	if (acc != null) {
    		AccessController.doPrivileged(new PrivilegedAction<Object>() {
    			public Object run() {
    				ApplicationContextAwareProcessor.this.invokeAwareInterfaces(bean);
    				return null;
    			}
    		}, acc);
    	} else {
    		this.invokeAwareInterfaces(bean);//2
    	}
    
    	return bean;
    }
    

    注释1:创建User对象,初始化之前,先判断User类是否实现了ApplicationContextAware接口

    注释2:调用invokeAwareInterfaces方法给bean设置值

    private void invokeAwareInterfaces(Object bean) {
    	if (bean instanceof Aware) {
    		if (bean instanceof EnvironmentAware) {
    			((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
    		}
    
    		if (bean instanceof EmbeddedValueResolverAware) {
    			((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);
    		}
    
    		if (bean instanceof ResourceLoaderAware) {
    			((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
    		}
    
    		if (bean instanceof ApplicationEventPublisherAware) {
    			((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);
    		}
    
    		if (bean instanceof MessageSourceAware) {
    			((MessageSourceAware)bean).setMessageSource(this.applicationContext);
    		}
    
    		if (bean instanceof ApplicationContextAware) {
    			((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
    		}
    	}
    
    }
    

     invokeAwareInterfaces方法中判断该bean属于哪个Aware实例,并进行相应设值处理。如果Aware是ApplicationContextAware,就将当前bean转成ApplicationContextAware类型并调用setApplicationContext方法将ApplicationContext值设置到bean中

    调试:

      在bean是User类型时,setApplicationContext方法会得到执行,也即user对象中设置了ioc容器,可以在user的其它方法中使用该容器

    BeanValidationPostProcessor

    数据校验

    常用

      对象创建完成,bean对象属性赋值后,web中应用比较多

      对页面提交的值进行校验

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    	if (!this.afterInitialization) {
    		this.doValidate(bean);
    	}
    
    	return bean;
    }
    
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    	if (this.afterInitialization) {
    		this.doValidate(bean);
    	}
    
    	return bean;
    }
    

    postProcessBeforeInitialization方法用于初始化前校验

    postProcessAfterInitialization方法用于初始化后校验

    InitDestroyAnnotationBeanPostProcessor

    该处理器用于处理@PostConstruct、@PreDestroy注解

    利用反射调用bean生命周期的相关方法

  • 相关阅读:
    idea+maven使用
    MySQL数据库一个字段对应多个值得模糊查询
    什么时候用接口?什么时候用抽象类?
    线程的死锁和死锁解决的实际案例
    idea 实用插件
    linux查看日志报错
    mysql日期模糊查找的方法
    mysql 日期函数
    win10安装sonarqube
    docker中mysql数据库导出部分数据
  • 原文地址:https://www.cnblogs.com/qf123/p/10931837.html
Copyright © 2011-2022 走看看