了解BeanPostProcessor

在公司disConf分享会上,听到一个名词,BeanPostProcessor,后来在网上搜了一下,发现使用BeanPostProcessor可以解决很多看似很困难的问题。

简介

BeanPostProcessor是spring提供的一个扩展接口

public interface BeanPostProcessor {
    //bean初始化方法调用前被调用
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    //bean初始化方法调用后被调用
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

当一个BeanPostProcessor注册到spring容器中后,对于容器在创建每一个bean时,在初始化方法调用前会调用postProcessBeforeInitialization(Object bean, String beanName)方法,在初始化方法完成后会调用postProcessorAfterInitialization(Object bean, String beanName),也就是说,spring给了我们一个机会对生成的bean进行再改造,可以修改bean的属性,将属性指向代理类或者直接生成一个bean代理返回。

下面举例为获取bean属性然后改变其引用。

先写一个注解RemoteService

@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RemoteService {
}

再写一个远程代理类

public class RemoteProxy implements InvocationHandler {

    Remote remote = new Remote();

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return remote.invokeRemote(method, args);
    }
}

远程实现类的接口

public interface UserService {

    /**
     * 根据userId获取User信息
     * @param userId userId
     * @return userInfo
     */
    Object getUser(Long userId);
}

在controller里调用使用此接口

public class UserController {

    @RemoteService
    UserService userService;

    Object getUser(){
        return userService.getUser(1L);
    }

}

下面是RemoteProxyBeanPostProcessor

public class RemoteServiceBeanPostProcessor implements BeanPostProcessor {

    RemoteProxy remoteProxy = new RemoteProxy();

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class clazz = bean.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for(Field field : fields) {
            if (field.isAnnotationPresent(RemoteService.class)) {
                try {
                    field.set(bean, remoteProxy);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        return bean;
    }
}

当UserController被spring实例化后,会调用RemoteServiceBeanPostProcessor里的RemoteServiceBeanPostProcessor方法,治理直接返回实例化后的bean,接着调用userController的初始化方法,最后调用RemoteServiceBeanPostProcessor里的postProcessorAfterInitialization方法,这个方法里获取到了userController里使用了RemoteService注解的field,将RemoteProxy注入到该属性中,这样在调用userService时,实际上是走的RemoteProxy代理类

猜你喜欢

转载自blog.csdn.net/zongyeqing/article/details/80358364