手写spring源码--spring前置后置处理器和spring代理机制

Bean的前置后置处理器

Bean的后置处理器,可以利用这个机制去处理我们的Bean,我可能希望对Bean创建的过程去做一些控制,因此我们需要一个接口,这个接口是spring那边的

public interface BeanPostProcessor {
    public void postProcessBeforeInitialization(String beanName, Object bean);
    public void postProcessAfterInitialization(String beanName, Object bean);
}

我们自己的实现类这个肯定是在自己相关代码写的,需要Component注解因为要交给spring来管理

@Component
public class ZhouyuBeanPostProcessor implements BeanPostProcessor {
    @Override
    public void postProcessBeforeInitialization(String beanName, Object bean) {
        if ()
    }

    @Override
    public void postProcessAfterInitialization(String beanName, Object bean) {

    }
}

我们需要一个List保存需要对Bean前置处理和后置处理的集合,List中保存的对象就是Bean处理器接口

private ArrayList<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();

扫描的过程中添加到list中

//根据类型获取相应的class对象
Class<?> clazz = classLoader.loadClass(className);
//有Component注解 需要注入
if (clazz.isAnnotationPresent(Component.class)) {

    if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
        BeanPostProcessor instance = (BeanPostProcessor) clazz.newInstance();
        beanPostProcessorList.add(instance);
    }

依旧是在创建bean方法中实现前置后置处理器逻辑 这也是Bean的生命周期中的一环

private Object createBean(String beanName, BeanDefinition beanDefinition) {

    //判断Bean对象是不是实现了BeanNameAware接口
    // bean的名字回调
    if (instance instanceof BeanNameAware) {
        ((BeanNameAware)instance).setBeanName(beanName);
    }
    //具体的方法我们并不关心 由由用户自定义
    for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
        beanPostProcessor.postProcessBeforeInitialization(beanName,instance);
    }



    //初始化 初始化逻辑是自己选的 如果在构造器中写的话就有问题了
    //因为不可选创建时必然会调用
    if (instance instanceof InitializingBean) {
        ((InitializingBean)instance).afterPropertiesSet();
    }
    // BeanPostProcessor  初始化后 AOP 后置处理器
    for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
        beanPostProcessor.postProcessAfterInitialization(beanName,instance);
    }
}

创建代理对象

创建bean返回的应该是代理对象 但是现在的返回的就是对象本身 我们要求的是返回代理对象

@Component
public class ZhouyuBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(String beanName, Object bean) {
        if (beanName.equals("userService")) {
            System.out.println("1111");
        }
        return bean;
    }
    //传进来的是一个bean对象返回的是一个 代理对象
    @Override
    public Object postProcessAfterInitialization(String beanName, Object bean) {
        //如果是UserService对象 返回其代理对象
        if (beanName.equals("userService")) {
            Object proxyInstance = Proxy.newProxyInstance(ZhouyuBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override //proxy是代理对象   method代理对象正在执行的那个方法
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                    System.out.println("切面逻辑");//这个就是增强方法,然后再执行本来的方法
                    return method.invoke(bean,args);
                }
            });
            return proxyInstance;
        }
        return bean;
    }
}

相关信息

  1. 方法作用
    postProcessAfterInitialization 是 Spring 生命周期钩子,在所有 Bean 的初始化阶段结束后执行。此时传入的 bean 是已经被 Spring 初始化的原始对象。

  2. 条件筛选
    通过 beanName.equals("userService") 定位特定 Bean,仅对 "userService" 进行代理增强。

  3. 动态代理
    使用 JDK 动态代理(Proxy.newProxyInstance)创建代理对象:

    • 类加载器ZhouyuBeanPostProcessor.class.getClassLoader()
    • 代理接口bean.getClass().getInterfaces()(代理目标对象实现的所有接口)
    • InvocationHandler:定义代理对象的拦截逻辑
  4. 核心拦截逻辑
    在 InvocationHandler.invoke() 中完成增强:

    public Object invoke(Object proxy, Method method, Object[] args) {
      System.out.println("切面逻辑");  // 增强逻辑(如日志、权限校验等)
      return method.invoke(bean, args); // 调用原始对象的方法
    }
    

关于 method 参数的解释

  • java.lang.reflect.Method 对象,代表当前被调用的目标方法
  • 包含的信息
    • 方法签名(方法名、参数类型、返回类型等)
    • 方法的元数据(注解、修饰符等)
  • 作用场景
    当通过代理对象调用任何方法时(例如 userService.login()),此处的 method
    1. 对应被调用的具体方法(如 login()
    2. args 包含调用时的实际参数
    3. 通过反射 method.invoke(bean, args) 将请求转发给原始 Bean

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值