BeanPostProcessor

BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口。接口声明如下:

 
  1. 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());
      }
   }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值