this() | If the proxy class matches the specified class according to the type, then all connection points of the target class to be proxy match the tangent point |
In general, this() and target() are used to match and define pointcuts. They are equivalent. The difference between them is reflected in the specific performance of generating proxy objects through the reference plane.
1,Factory
package com.test.aspectj.expression; /** * Factory interface */ public interface Factory { // Make products void make(); // transport void delivery(String address); }
2,PhoneFactory
package com.test.aspectj.expression; import com.test.aspectj.expression.args.FreshFoodFactory; import com.test.aspectj.expression.args.FrozenFoodFactory; import org.springframework.stereotype.Component; /** * Food factory */ @Component public class FoodFactory implements Factory { // How to make products @Override public void make() { System.out.println("From target class FoodFactory News of: food production"); } // transport @Override public void delivery(String address) { System.out.println("From target class FoodFactory Sales of food to " + address); } // Match to @ args(com.test.aspectj.expression.args.Listen) pointcut public void testArgsAnnotation(FreshFoodFactory freshFoodFactory) { } // Cannot match @ args(com.test.aspectj.expression.args.Listen) pointcut public void testFrozenArgsAnnotation(FrozenFoodFactory frozenFoodFactory) { } }
3. Introduce the interface Listener to be implemented
package com.test.aspectj.expression.thisexpression; /** * Interface to be implemented in the introduction section */ public interface Listener { /** * Monitor */ void listen(); }
4. Listener interface implementation class
package com.test.aspectj.expression.thisexpression; /** * Listener Interface implementation class */ public class DefaultListener implements Listener { /** * Monitor */ @Override public void listen() { System.out.println("Come from DefaultListener Start listening"); } }
5. Define the reference facet ListenerAspect, which populates the Listener interface for FoodFactory
package com.test.aspectj.expression.thisexpression; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.DeclareParents; import org.springframework.core.Ordered; /** * Add a facet of the Listener interface to FoodFactory */ @Aspect public class ListenerAspect implements Ordered { /** * Add interface implementation for FoodFactory. The interface to be implemented is Listener. The default implementation of the interface is DefaultListener */ @DeclareParents(value = "com.test.aspectj.expression.FoodFactory", defaultImpl = DefaultListener.class) public static Listener listener; /** * If there are multiple cuts, pay attention to the order in which the cuts are woven */ @Override public int getOrder() { return 2; } }
6. Test this and target facets
package com.test.aspectj.expression.thisexpression; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.core.Ordered; import javax.annotation.Resource; /** * Test the tangent of this and target */ @Aspect public class ThisAspect implements Ordered { /** * Weaving into a Bean whose runtime object is Listener type * * You can match not only the methods defined in the Listener interface, but also the methods in FoodFactory */ @AfterReturning("this(com.test.aspectj.expression.thisexpression.Listener)") public void after() { System.out.println("Message from the section: ThisAspect after Method executed"); } /** * Match only the methods defined in the Listener */ @Before("target(com.test.aspectj.expression.thisexpression.Listener)") public void before() { System.out.println("Message from the section: ThisAspect before Method executed"); } /** * If there are multiple cuts, pay attention to the order in which the cuts are woven */ @Override public int getOrder() { return 1; } }
7,xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.test.aspectj.expression"/> <bean id="listenerAspect" class="com.test.aspectj.expression.thisexpression.ListenerAspect"/> <bean id="thisAspect" class="com.test.aspectj.expression.thisexpression.ThisAspect"/> <aop:aspectj-autoproxy /> </beans>
8. Test code
package com.test.aspectj.expression.thisexpression; import com.test.aspectj.expression.FoodFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * test */ public class ThisExpressionDemo { public static void main(String[] args) { System.out.println("=============== test this ==============="); ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-chapter3-aspectjthisexpression.xml"); FoodFactory foodFactory = (FoodFactory) context.getBean("foodFactory"); foodFactory.make(); System.out.println("-----Dividing line-----"); Listener listener = (Listener) foodFactory; listener.listen(); } }
9. The theoretical results are as follows
===============Test this=============== Message from the target class FoodFactory: produce food Message from aspect: ThisAspect after method executed -----Dividing line----- Message from the aspect: ThisAspect before method executed Message from DefaultListener: start listening Message from aspect: ThisAspect after method executed
However, errors are reported in the test process as follows (it is also necessary to verify the correctness of the conclusion)
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy16 cannot be cast to com.test.aspectj.expression.FoodFactory at com.test.aspectj.expression.thisexpression.ThisExpressionDemo.main(ThisExpressionDemo.java:14)
10, summary
- this(com.test.aspectj.expression.thisexpression.Listener) can match not only the methods defined in the listener interface, but also the methods in FoodFactory;
- target(com.test.aspectj.expression.thisexpression.Listener) only matches the methods defined in the listener.