ClassFilter
和 MethodMatcher
,其实可以很好的理解,如何定义一个切入点?我们在定义切入点的时候,就是想对某一个类的全部方法,或者对某一个类的部方法进行切入,因此在判断能否作用到方法上的时候,先判断是否类能够匹配(ClassFilter的活),之后再判断方法是否匹配(MethodMatcher的活)。 AspectJExpressionPointcut
【这个类主要是解析execution表达式的,这个类同时实现了ClassFilter和MethodMatcher,具备了两者的功能,因此可以直接使用该类进行切入点的匹配】、 AnnotationMatchingPointcut
【注解的PointCut,主要用来匹配注解,底层使用就是 AnnotationMethodMatcher
和 AnnotationMethodClassFilter
,后续会讲到】 源码如下:
public interface Pointcut{ //返回一个ClassFilter ClassFiltergetClassFilter(); //返回一个MethodMatcher MethodMatchergetMethodMatcher(); //TruePointCut,对应任何的方法都是匹配(总是匹配) Pointcut TRUE = TruePointcut.INSTANCE; }
AspectJExpressionPointcut
演示如下:
@Test public void testAspectJExpressionPointCut()throws NoSuchMethodException { AspectJExpressionPointcut expressionPointcut = new AspectJExpressionPointcut(); //设置aspectj表达式,这个比较常用的表达式 expressionPointcut.setExpression("execution(* cn.tedu.demo.service.UserService.addUser(..))"); //匹配类 boolean b = expressionPointcut.matches(UserService.class); //直接调用matches匹配方法 boolean a = expressionPointcut.matches(UserService.class.getDeclaredMethod("addUser", User.class), UserService.class); System.out.println(a+"--->"+b); }
@Test public void testAnnotationMatchingPointcut()throws NoSuchMethodException { //第一个参数是注解,第二参数表示是否在接口和父类的查找该注解 AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(Transactional.class, false); //匹配方法上是否有@Transactional注解 boolean a = pointcut.getMethodMatcher().matches(UserService.class.getDeclaredMethod("addUser", User.class), UserService.class); //匹配类上是否有@Transactional注解 boolean b = pointcut.getClassFilter().matches(UserService.class); System.out.println(a+"--->"+b); }
@Test public void testPointcuts()throws NoSuchMethodException { AnnotationMatchingPointcut annotationMatchingPointcut = new AnnotationMatchingPointcut(Transactional.class, false); Class cls=UserService.class; Method method = cls.getDeclaredMethod("addUser", User.class); //调用matches方法,判断UserService的addUser方法是否有@Transactional注解 boolean matches = Pointcuts.matches(annotationMatchingPointcut, method, cls); System.out.println(matches); }
@FunctionalInterface public interface ClassFilter{ //判断方法 boolean matches(Class<?> clazz); //定义一个总是匹配的TrueClassFilter,其实就是matches方法总是返回true ClassFilter TRUE = TrueClassFilter.INSTANCE; }
ClassFilter在spring底层有许多实现的类,比如AnnotationClassFilter(匹配指定注解)、TrueClassFilter(全部匹配)、AspectJExpressionPointcut(Aspect表达式匹配,APO重要的组件)
实例:使用AnnotationClassFilter测试该类是否有 @Transactional
注解
checkInherited
,如果为false,那么只检查当前类是否有对应的注解,为true,那么会检查父类或者实现的接口存在,默认为false @Test public void testAnnotationClassFilter(){ //指定checkInherited为true,会同时检查该类和父类及其实现的接口是否存在Transactional注解 AnnotationClassFilter annotationClassFilter = new AnnotationClassFilter(Transactional.class, true); boolean matches = annotationClassFilter.matches(UserServiceImpl.class); System.out.println(matches); }
我们也可以自定义自己的ClassFilter, 只需要实现其中的接口方法即可,如下:
@Test public void testCustomClassFilter(){ //自定义一个classFilter,判断指定的类是否是UserServiceImpl的接口或者父类或者同类 ClassFilter customFilter =cls-> cls.isAssignableFrom(UserServiceImpl.class); boolean matches = customFilter.matches(UserService.class); System.out.println(matches); }
UnionClassFilter
【满足其中一个即返回true】、 IntersectionClassFilter
【必须满足所有的ClassFilter才返回true】 public static ClassFilter union(ClassFilter cf1, ClassFilter cf2) public static ClassFilter intersection(ClassFilter cf1, ClassFilter cf2)
@Test public void testClassFilters(){ //类或者接口上必须有Transactional注解 AnnotationClassFilter annotationClassFilter = new AnnotationClassFilter(Transactional.class,false); //类或者接口必须是UserServiceImpl的父类或者接口或者同类 ClassFilter customFilter =cls-> cls.isAssignableFrom(UserServiceImpl.class); //返回unionFilter,只要满足上面的一个ClassFilter即返回true ClassFilter unionFilter = ClassFilters.union(annotationClassFilter, customFilter); //返回intersectionFilter,必须满足上面两个ClassFilter才会返回true ClassFilter intersectionFilter = ClassFilters.intersection(annotationClassFilter, customFilter); boolean u = unionFilter.matches(UserService.class); boolean i = intersectionFilter.matches(UserService.class); System.out.println(u); System.out.println(i); }
接口的实现类有很多,如 StaticMethodMatcher
【只支持静态匹配,两个参数的matchs】、 AspectJExpressionPointcut
【AOP重要组件】、 TrueMethodMatcher
【总是匹配】、 AnnotationMethodMatcher
【注解匹配】
实例如下:
@Test public void testAnnotationMethodMatcher()throws NoSuchMethodException { //检测方法上是否标注了Transactional注解,false指定了不检查当前类父类和接口 AnnotationMethodMatcher methodMatcher=new AnnotationMethodMatcher(Transactional.class,false); Class cls=UserService.class; Method method = cls.getDeclaredMethod("addUser", User.class); //两个参数的mathces,三个参数的不支持【继承了StaticMethodMatcher】 boolean matches = methodMatcher.matches(method, cls); System.out.println(matches); }
UnionMethodMatcher类
【只要匹配一个即返回true】, IntersectionMethodMatcher
【】 BeforeAdvice
、 AfterAdvice
等 AbstractAspectJAdvice
,各种AspectJ的通知都会继承并拓展该类,其中封装了有关通知的全部信息,比如方法名称、方法Method对象、PointCut、Jpoint、pointCut表达式等等信息,其中最重要的一个方法就是 protected Object invokeAdviceMethodWithGivenArgs(Object[] args)
,该方法用于调用通知方法。 AspectJXxxAdvice
,继承抽象类 AbstractAspectJAdvice
。 AspectAfterAdvice
这个实现类,其中重要的方法就是invok,源码如下:
public Object invoke(MethodInvocation mi)throws Throwable { try { //先执行被增强的方法 return mi.proceed(); } finally { //再执行通知方法 invokeAdviceMethod(getJoinPointMatch(), null, null); } }
AspectJExpressionPointcutAdvisor
org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
public AopProxy createAopProxy(AdvisedSupport config)throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } //如果是接口,创建JDK的动态代理 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { //创建Cglib动态代理 return new JdkDynamicAopProxy(config); } }
public class ProxyFactoryTest{ /** * 自定义一个BeforeAdvice */ public static class CustomBeforAdviceimplements MethodBeforeAdvice{ @Override public void before(Method method, Object[] args, Object target)throws Throwable { String name = method.getName(); if (StringUtils.equals(name,"addUser")){ System.out.println("在addUser之前执行"); }else{ System.out.println("other"); } } } public static class Log{ public void before(){ System.out.println("在之前执行"); } } @Test public void test1(){ UserService userService=new UserServiceImpl(); //创建proxyFactory ProxyFactory factory = new ProxyFactory(userService); //创建自定义的BeforeAdvice MethodBeforeAdvice advice=new CustomBeforAdvice(); //将Advice添加到proxyFactory中 factory.addAdvice(advice); //获取代理对象 UserService proxy = (UserService) factory.getProxy(); proxy.addUser(new User("")); } @Test public void test2()throws NoSuchMethodException { UserService userService=new UserServiceImpl(); //创建proxyFactory ProxyFactory factory = new ProxyFactory(userService); Class aspectCls=Log.class; Method aspectMethod = aspectCls.getMethod("before"); //构建aspectJ表达式切入点 AspectJExpressionPointcut aspectJExpressionPointcut = new AspectJExpressionPointcut(); aspectJExpressionPointcut.setExpression("execution(* cn.tedu.demo.service.UserService.addUser(..))"); //创建AspectInstanceFactory(切面实例工厂) AspectInstanceFactory aspectInstanceFactory=new SimpleAspectInstanceFactory(aspectCls); AspectJMethodBeforeAdvice advice=new AspectJMethodBeforeAdvice(aspectMethod,aspectJExpressionPointcut,aspectInstanceFactory); //创建Advisor,其中封装了Advice和Advisor Advisor advisor = new AspectJPointcutAdvisor(advice); ArrayList<Advisor> advisors = Lists.newArrayList(advisor); //添加ExposeInvocationInterceptor到advisor中,这个不是必须的,但是使用AspectJ expression pointcut是必须的 AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(advisors); //将advisor添加到ProxyFactory中 factory.addAdvisors(advisors); UserService proxy= (UserService) factory.getProxy(); proxy.addUser(new User("chen")); } }
@EnableAspectJAutoProxy
该注解中可以看出使用了 @Import(AspectJAutoProxyRegistrar.class)
,因此实际作用的类就是 AspectJAutoProxyRegistrar
。 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy {
ImportBeanDefinitionRegistrar AnnotationAutoProxyCreator
class AspectJAutoProxyRegistrarimplements ImportBeanDefinitionRegistrar{ /** * 向容器中注入AnnotationAutoProxyCreator */ @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //调用方法注册AnnotationAutoProxyCreator AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); //获取@EnableAspectJAutoProxy注解中两个属性的值 AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); //判断注解属性的值 if (enableAspectJAutoProxy != null) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } }
SmartInstantiationAwareBeanPostProcessor
创建代理对象的代码如下:
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey){ if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } //如果为false,直接返回,不需要代理 if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } //判断是否是基础的切面类 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // 获取适用的Advisor Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //创建代理对象 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } //org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } //创建代理工厂 ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(getProxyClassLoader()); }
AbstractAdvisorAutoProxyCreator
ReflectiveAspectJAdvisorFactory
是其实现类,AOP中就是使用该类构造Advisor private List<Method> getAdvisorMethods(Class<?> aspectClass) public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory)
private final AdvisedSupport advised
:其中封装了代理类的属性,其实就是一个ProxyFactory,包括目标类,目标方法、advisor等信息。 public Object invoke(Object proxy, Method method, Object[] args)
:方法调用的类,实现了InvocationHandler的方法 Object invoke(MethodInvocation invocation) throws Throwable
mi.proceed()
这个方法,是责任链模式的重要方法。 @Override public Object invoke(MethodInvocation mi)throws Throwable { try { //调用其他的拦截器【因为这个拦截器是在方法之后执行的】 return mi.proceed(); } finally { //最终调用通知方法 invokeAdviceMethod(getJoinPointMatch(), null, null); } }
proceed
,通过责任链的模式执行拦截器中的方法,和MethodInterceptor完美的诠释了责任链设计模式。源码如下:
public Object proceed()throws Throwable { // 标记拦截器链执行的位置,初始值是-1,递归的结束条件 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { //拦截器都执行完成了,那么通过反射执行目标方法 return invokeJoinpoint(); } //获取拦截器 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); //判断拦截器的类型 if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass()); if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { return proceed(); } } else { //调用拦截器的invoke方法 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
@Test public void test1()throws Throwable { //目标对象 UserService userService=new UserServiceImpl(); //新建一个ProxyFactory,创建代理 ProxyFactory factory = new ProxyFactory(); factory.setTarget(userService); //设置接口,否则使用的是cglib代理 factory.setInterfaces(UserService.class); //获取代理对象 Object proxy = factory.getProxy(); //切面 Class aspectCls=LogAspect.class; //通知方法 Method aspectMethod=aspectCls.getDeclaredMethod("afterAdvice"); //切面对象 final Object aspectObj=new LogAspect(); //新建一个拦截器 MethodInterceptor afterInterceptor=new MethodInterceptor() { @Override public Object invoke(MethodInvocation invocation)throws Throwable { CustomeInvocation ref=(CustomeInvocation)invocation; try{ //执行其他的拦截器 return invocation.proceed(); }finally { //最后执行切面的方法 ref.getAspectMethod().invoke(ref.getAspectObj(), ref.getAspectArgs()); // System.out.println("方法之后执行"); } } }; //创建拦截器链 List<Object> interceptors=new ArrayList<>(); interceptors.add(afterInterceptor); Method targetMethod=UserService.class.getMethod("addUser", User.class); Object[] args=new Object[]{new User("陈加兵")}; CustomeInvocation invocation = new CustomeInvocation(proxy, userService, targetMethod, args, UserService.class,interceptors,aspectCls,aspectMethod,aspectObj,new Object[]{}); invocation.proceed(); } /** * 自定义一个Invocation,因为ReflectiveMethodInvocation是spring内部使用的,构造方法protected */ public static class CustomeInvocationextends ReflectiveMethodInvocation{ private Method aspectMethod; private Class aspcetCls; private Object aspectObj; private Object[] aspectArgs; /** * @param proxy 代理 * @param target 目标对象 * @param method 目标方法 * @param arguments 参数 * @param targetClass 目标类 * @param aspectMethod 通知方法 * @param aspctCls 切面类 * @param aspectObj 切面对象 * @param interceptorsAndDynamicMethodMatchers 拦截器 */ public CustomeInvocation(Object proxy, Object target, Method method, Object[] arguments, Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers,Class aspctCls,Method aspectMethod,Object aspectObj,Object[] aspectArgs){ super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers); this.aspectMethod=aspectMethod; this.aspcetCls=aspctCls; this.aspectObj=aspectObj; this.aspectArgs=aspectArgs; } }
public class JDKDynamicProxy{ public static interface Subject{ int add(int a,int b); } public static class CustomSubjectimplements Subject{ @Override public int add(int a, int b){ System.out.println("执行加法计算"); return a+b; } } /** * 自定义的InvocationHandler */ public static class CustomInvocationHandlerimplements InvocationHandler{ /** * 目标对象 */ private Object targetObject; public CustomInvocationHandler(Object targetObject){ this.targetObject = targetObject; } /** * @param proxy 代理对象 * @param method 真正执行的方法 * @param args 方法参数 * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args)throws Throwable { String methodName = method.getName(); if (methodName.equals("add")){ System.out.println("invok调用"); Object invoke = method.invoke(targetObject, args); return invoke; } return null; } } @Test public void test(){ Subject subject=new CustomSubject(); CustomInvocationHandler customInvocationHandler = new CustomInvocationHandler(subject); Subject proxy= (Subject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[]{Subject.class}, customInvocationHandler); int count = proxy.add(1, 2); System.out.println(count); } }