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;
}