Spring Bean 后置处理器BeanPostProcessor

文章目录

    • Spring Bean 后置处理器BeanPostProcessor
    • BeanPostProcessor实现类代码演示
    • BeanPostProcessor生成代理对象

Spring Bean 后置处理器BeanPostProcessor

Spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after()

可以配置多个 BeanPostProcessor 接口,通过设置 BeanPostProcessor 实现的 Ordered 接口提供的 order 属性来控制这些 BeanPostProcessor 接口的执行顺序。

ApplicationContext 会自动检测由 BeanPostProcessor 接口的实现定义的 bean,注册这些 bean 为后置处理器,然后通过在容器中创建 bean,在适当的时候调用它。

Spring Bean 后置处理器BeanPostProcessor_第1张图片

  • Factory hook(勾子) that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.

  • spring提供工厂勾子,用于修改实例对象,可以生成代理对象,是AOP底层。

    模拟
    A a =new A();
    a = B.before(a) --> 将a的实例对象传递给后处理bean,可以生成代理对象并返回。
    a.init();
    a = B.after(a);
    a.addUser(); //生成代理对象,目的在目标方法前后执行(例如:开启事务、提交事务)
    a.destroy()

BeanPostProcessor实现类代码演示

  • BeanPostProcessor实现类1,同时实现getOrder方法来控制这些 执行顺序
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;

public class PostProcessor implements BeanPostProcessor,Ordered {

    //可以在初始化 bean 的之前和之后实现更复杂的逻辑。
    //在Init-method的前后执行
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization1:" + beanName);
        ((InitHelloWorld)bean).getMessage();
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization1:" + beanName);
        ((InitHelloWorld)bean).getMessage();
        return bean;
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
  • BeanPostProcessor实现类2
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;

public class PostProcessor2 implements BeanPostProcessor,Ordered {

    //可以在初始化 bean 的之前和之后实现更复杂的逻辑。
    //在Init-method的前后执行
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization2:" + beanName);
        ((InitHelloWorld)bean).getMessage();
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization2:" + beanName);
        ((InitHelloWorld)bean).getMessage();
        return bean;
    }

    @Override
    public int getOrder() {
        return 1;
    }
}

  • 配置




    
        
    

    
    


  • InitHelloWorld
public class InitHelloWorld{
    private String message;

    public void setMessage(String message){
        this.message  = message;
    }
    public void getMessage(){
        System.out.println("Your Message : " + message);
    }
    public void init(){
        System.out.println("Bean is going through init.");
    }
    public void destroy(){
        System.out.println("Bean will destroy now.");
    }
}

  • 测试
    @Test
    public void demo(){
        String xmlPath = "lifecycle2.xml";
        AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        InitHelloWorld initHelloWorld = applicationContext.getBean("initHelloWorld",InitHelloWorld.class);
        initHelloWorld.getMessage();
        applicationContext.registerShutdownHook();
    }

Spring Bean 后置处理器BeanPostProcessor_第2张图片

BeanPostProcessor生成代理对象

  • MyBeanPostProcessor
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyBeanPostProcessor implements BeanPostProcessor {

	@Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("前方法 : " + beanName);
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
		System.out.println("后方法 : " + beanName);
		// bean 目标对象
		// 生成 jdk 代理
		return Proxy.newProxyInstance(
					MyBeanPostProcessor.class.getClassLoader(), 
					bean.getClass().getInterfaces(), 
					new InvocationHandler(){
						@Override
						public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
							System.out.println("------开启事务");
							System.out.println("调用方法:" + method.getName());
							//执行目标方法
							Object obj = method.invoke(bean, args);
							
							System.out.println("------提交事务");
							return obj;
						}});
	}
}

  • 配置



    
    
    
    



  • BookDaoImpl
public class BookDaoImpl implements BookDao {

	@Override
	public void addBook() {
		System.out.println("di add book");
	}

}

  • 测试
    @Test
    public void demo(){
        String xmlPath = "lifecycle3.xml";
        AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        BookDao bookDao = applicationContext.getBean("bookDaoId",BookDao.class);
        bookDao.addBook();
    }

Spring Bean 后置处理器BeanPostProcessor_第3张图片

注意:
问题1:后处理bean作用某一个目标类,还是所有目标类?
所有
问题2:如何只作用一个?
通过“参数2”beanName进行控制

你可能感兴趣的:(Spring)