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

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

拦截器链

BeforeAdvice

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

package com.linnine.spring.aop;

/**
 * 13 拦截器链
 */
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;

/**
 * 13 访问者
 */
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<AspectJExpressionPointcutAdvisor> 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;

    }

    /**
     * 是否是以下某个类的子类
     * @param beanClass
     * @return
     */
    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

<?xml version="1.0" encoding="UTF-8"?>
<beans>

<!--
    <bean id="userDao" class="com.linnine.spring.bean.dao.UserDao" init-method="initDataMethod" destroy-method="destroyDataMethod"/>
-->

<!--
    <bean id="proxyUserDao" class="com.linnine.spring.bean.ProxyBeanFactory"/>
-->

    <bean id="userService" class="com.linnine.spring.bean.service.UserService" scope ="prototype"/>

    <bean class="com.linnine.spring.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

    <bean id="beforeAdvice" class="com.linnine.spring.bean.UserServiceBeforeAdvice"/>

    <bean id="methodInterceptor" class="com.linnine.spring.aop.framework.adapter.MethodBeforeAdviceInterceptor">
        <property name="advice" ref="beforeAdvice"/>
    </bean>
    <bean id="pointcutAdvisor" class="com.linnine.spring.aop.aspectj.AspectJExpressionPointcutAdvisor">
        <property name="expression" value="execution(* com.linnine.spring.bean.service.IUserService.*(..))"/>
        <property name="advice" ref="methodInterceptor"/>
    </bean>
<!--    <bean class="com.linnine.spring.event.CustomEventListener" />
    <bean class="com.linnine.spring.event.CustomRefreshedEventListener" />
    <bean class="com.linnine.spring.event.CustomClosedEventListener" />-->

    <!--    <bean class="com.linnine.spring.common.MyBeanFactoryPostProcessor"/>
        <bean class="com.linnine.spring.common.MyBeanPostProcessor"/>-->
</beans>

测试方法

@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;
在这里插入图片描述
之前是直接实例化对象, 现在会先判断是否为代理对象, 如果是就通过代理生成

继续加代码

/**
 * 判断是否为代理对象
 * @param beanName
 * @param beanDefinition
 * @return
 */
protected Object resolveBeforeInstantiation(String beanName, BeanDefinition beanDefinition) {
    //若果能通过这个实例化创建对象(是代理类)
    Object bean = applyBeanPostProcessorsBeforeInstantiation(beanDefinition.getBeanClass(), beanName);
    if (null != bean) {
        //创建成功时 执行初始化后的操作 上面那个是实例化前的操作 取代了 初始化前的操作
        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    }
    return bean;
}
/**
 * 实例化前
 * @param beanClass
 * @param beanName
 * @return
 */
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值