栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

手撸spring13: aop动态代理插手bean的生命周期

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

手撸spring13: aop动态代理插手bean的生命周期

aop动态代理可以在对象操作执行时,补充一些骚操作, 而且因为是通过方法名进行匹配的, 对象自己不用额外操作,可以说是无感的! 比较常见的场景就是 接口调用时间的记录了.

拦截器链

BeforeAdvice

定义一个拦截器链,这里简单的写个before, 不然还有after之类的.

package com.linnine.spring.aop;

public interface BeforeAdvice extends Advice {
}
MethodBeforeAdvice

然后做一个方法执行前

package com.linnine.spring.aop;

public interface MethodBeforeAdvice extends BeforeAdvice{

    void before(Method method,Object[] args,Object target) throws Throwable;
}
Advisor

访问者用来获取上面的哪些Advice
package com.linnine.spring.aop;

public interface Advisor {

    Advice getAdvice();
}
PointcutAdvisor

切点访问者, 组合起来 用于获取切点和advice

package com.linnine.spring.aop;

public interface PointcutAdvisor extends Advisor {

    Pointcut getPointcut();
}
AspectJExpressionPointcutAdvisor

一个简单的实现类

package com.linnine.spring.aop.aspectj;

@Data
public class AspectJExpressionPointcutAdvisor implements PointcutAdvisor {

    private AspectJExpressionPointcut pointcut;

    private Advice advice;

    private String expression;

    @Override
    public Pointcut getPointcut() {
        if (pointcut == null){
            pointcut = new AspectJExpressionPointcut(expression);
        }
        return pointcut;
    }
}
MethodBeforeAdviceInterceptor

拦截器 用于前面的MethodBeforeAdvice 拦截后的处理操作
package com.linnine.spring.aop.framework.adapter;

public class MethodBeforeAdviceInterceptor implements MethodInterceptor {

    private MethodBeforeAdvice advice;

    public MethodBeforeAdviceInterceptor() {
    }

    public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
        this.advice = advice;
    }

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        this.advice.before(methodInvocation.getMethod(), methodInvocation.getArguments(), methodInvocation.getThis());
        return methodInvocation.proceed();
    }
}
ProxyFactory

代理工厂

package com.linnine.spring.aop.framework;

public class ProxyFactory {

    private AdvisedSupport advisedSupport;

    public ProxyFactory(AdvisedSupport advisedSupport) {
        this.advisedSupport = advisedSupport;
    }

    public Object getProxy(){
        return createAopProxy().getProxy();
    }

    private AopProxy createAopProxy() {
        if (advisedSupport.isProxyTargetClass()){
            return new Cglib2AopProxy(advisedSupport);
        }
        return new JdkDynamicAopProxy(advisedSupport);
    }
}
DefaultAdvisorAutoProxyCreator

然后做一个默认的访问者代理创建

package com.linnine.spring.aop.framework.autoproxy;

public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {

    private DefaultListableBeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = (DefaultListableBeanFactory) beanFactory;
    }

    @Override
    public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {

        //如果是切点/advice或者Advisor 直接返回空
        if (isInfrastructureClass(beanClass)) return null;

        //获取访问者集合
        Collection advisors = beanFactory.getBeansOfType(AspectJExpressionPointcutAdvisor.class).values();

        for (AspectJExpressionPointcutAdvisor advisor : advisors) {

            //获取切点相关的信息
            ClassFilter classFilter = advisor.getPointcut().getClassFilter();
            //如果不匹配的就退出
            if (!classFilter.matches(beanClass)) continue;

            //封装代理信息
            AdvisedSupport advisedSupport = new AdvisedSupport();

            //封装代理资源
            TargetSource targetSource = null;

            try {
                targetSource = new TargetSource(beanClass.getDeclaredConstructor().newInstance());
            } catch (Exception e) {
                e.printStackTrace();
            }
            advisedSupport.setTargetSource(targetSource);
            advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice());
            advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatcher());
            advisedSupport.setProxyTargetClass(false);
            //通过代理工厂生成代理对象
            return new ProxyFactory(advisedSupport).getProxy();

        }
        return null;

    }

    
    private boolean isInfrastructureClass(Class beanClass) {
        return Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass);
    }

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

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    
}
InstantiationAwareBeanPostProcessor

这里补一下父接口

package com.linnine.spring.beans.factory.config;

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor{

    Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException;
}
UserServiceBeforeAdvice

准备好了,做个外部实现

public class UserServiceBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("拦截方法:" + method.getName());
    }
}

配置spring








    

    

    

    
        
    
    
        
        
    


    

测试方法

@Test
public void test_aop13(){
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");

    IUserService userService = applicationContext.getBean("userService", IUserService.class);
    System.out.println("测试结果:" + userService.queryUserInfo());
}

测试结果

对了还要改造一下bean工厂里面的bean创建, 毕竟要插手到bean的生命周期

AbstractAutowireCapableBeanFactory

package com.linnine.spring.beans.factory.support;

之前是直接实例化对象, 现在会先判断是否为代理对象, 如果是就通过代理生成

继续加代码

protected Object resolveBeforeInstantiation(String beanName, BeanDefinition beanDefinition) {
    //若果能通过这个实例化创建对象(是代理类)
    Object bean = applyBeanPostProcessorsBeforeInstantiation(beanDefinition.getBeanClass(), beanName);
    if (null != bean) {
        //创建成功时 执行初始化后的操作 上面那个是实例化前的操作 取代了 初始化前的操作
        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    }
    return bean;
}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName) {
    //获取所有的bean后置处理器
    for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) {
        //如果是实现这个类的 比如前面写的DefaultAdvisorAutoProxyCreator
        if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
            //那么就执行这个postProcessBeforeInstantiation方法
            Object result = ((InstantiationAwareBeanPostProcessor) beanPostProcessor).postProcessBeforeInstantiation(beanClass, beanName);
            //对象不为空 就直接返回了
            if (null != result) return result;
        }
    }
    return null;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/963189.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号