BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口。接口声明如下:
-
public interface BeanPostProcessor { //bean初始化方法调用前被调用 Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; //bean初始化方法调用后被调用 Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
如上接口声明所示,BeanPostProcessor接口有两个回调方法。当一个BeanPostProcessor的实现类注册到Spring IOC容器后,对于该Spring IOC容器所创建的每个bean实例在初始化方法(如afterPropertiesSet和任意已声明的init方法)调用前,将会调用BeanPostProcessor中的postProcessBeforeInitialization方法,而在bean实例初始化方法调用完成后,则会调用BeanPostProcessor中的postProcessAfterInitialization方法,整个调用顺序可以简单示意如下:
--> Spring IOC容器实例化Bean
--> 调用BeanPostProcessor的postProcessBeforeInitialization方法
--> 调用bean实例的初始化方法
--> 调用BeanPostProcessor的postProcessAfterInitialization方法
可以看到,Spring容器通过BeanPostProcessor给了我们一个机会对Spring管理的bean进行再加工。比如:我们可以修改bean的属性,可以给bean生成一个动态代理实例等等。一些Spring AOP的底层处理也是通过实现BeanPostProcessor来执行代理包装逻辑的。
package com.dxfx.client;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.stereotype.Component;
import com.dxfx.client.annotation.RemoteInvoke;
import com.dxfx.client.model.Response;
@Component
public class InitalInvoke implements BeanPostProcessor{
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(bean.getClass().getName());
Field[] fields = bean.getClass().getDeclaredFields();
for(Field f: fields){
if(f.isAnnotationPresent(RemoteInvoke.class)){
RemoteInvoke remoteInvoke = f.getAnnotation(RemoteInvoke.class);
f.setAccessible(true);
Enhancer enhancer = new Enhancer();
enhancer.setInterfaces(new Class[]{f.getType()});
final Map<Method,Class> methodMap=new HashMap<Method,Class>();
putMethod(methodMap, f);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object instance, Method method, Object[] args, MethodProxy poxy) throws Throwable {
//调用netty客户端去处理
ClientRequest request = new ClientRequest();
request.setCommand(methodMap.get(method).getName()+"."+method.getName());
request.setContent(args[0]);
Response resp = TcpClient.send(request );
// Class<?>returnType = method.getReturnType();
return resp;
}
});
try {
f.set(bean, enhancer.create());
} catch (Exception e) {
e.printStackTrace();
}
}
}
return bean;
}
public static void putMethod(Map<Method,Class> methodMap,Field f){
for(Method m: f.getType().getDeclaredMethods()){
methodMap.put(m, f.getType());
}
}
}