target() | Restrict connection point matching to a class of the specified type |
@target() | Restrict join point matching target objects to classes annotated by specific annotations |
The function of within() is similar to that of execution(). The difference between the two is that the minimum range of connection points defined by within() is class level (not interface), while the minimum range of connection points defined by execution() can be accurate to the method parameters, so it can be considered that execution() covers the function of within().
"@ within()" matches the class marked with the specified annotation and its descendants.
Final class structure chart
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.annotation.Log; import org.springframework.stereotype.Component; /** * Mobile phone factory */ @Component public class PhoneFactory implements Factory { // How to make products @Override @Log public void make() { System.out.println("From target class PhoneFactory Message: making mobile phones"); } // How to transport mobile phones @Override public void delivery(String address) { System.out.println("From target class PhoneFactory Message for: Transport mobile phone to " + address); } // Test @ Within annotation public void testWithin() { } }
3,MobilePhoneFactory
package com.test.aspectj.expression.within; import com.test.aspectj.expression.PhoneFactory; import org.springframework.stereotype.Component; /** * Mobile phone factory */ @Monitor @Component public class MobilePhoneFactory extends PhoneFactory { @Override public void testWithin() { } }
4,IPhoneFactory
package com.test.aspectj.expression.within; import org.springframework.stereotype.Component; /** * iPhone Mobile phone factory */ @Component(value = "iPhoneFactory") public class IPhoneFactory extends MobilePhoneFactory { }
5. Custom annotation @Monitor
package com.test.aspectj.expression.within; import java.lang.annotation.*; /** * Monitor */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) @Documented public @interface Monitor { String value() default ""; }
6. Facet WithinAspect
package com.test.aspectj.expression.within; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; /** * Test the facets of within () and @ within() */ @Aspect public class WithinAspect { /** * FoodFactory The following method execution will be enhanced */ @Before("within(com.test.aspectj.expression.FoodFactory)") public void before() { System.out.println("Message from the section: within Match to, enhance before method execution"); } /** * There is @ Monitor annotation on the class. This class and its descendants can be enhanced */ @After("@within(com.test.aspectj.expression.within.Monitor)") public void after() { System.out.println("Message from the section:@within Match to, perform enhancement"); } }
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="annotationAspect" class="com.test.aspectj.expression.within.WithinAspect"/> <aop:aspectj-autoproxy proxy-target-class="true"/> </beans>
8. Test code
package com.test.aspectj.expression.within; import com.test.aspectj.expression.Factory; import com.test.aspectj.expression.PhoneFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Test within and @ within */ public class WithinExpressionDemo { public static void main(String[] args) { System.out.println("=============== test within ==============="); ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-chapter3-aspectjwithinexpression.xml"); Factory foodFactory = (Factory) context.getBean("foodFactory"); foodFactory.make(); System.out.println("-----I'm the divider-----"); foodFactory.delivery("Beijing"); System.out.println("=============== test @within ==============="); System.out.println("-----MobilePhoneFactory Annotations on it@Monitor-----"); MobilePhoneFactory mobilePhoneFactory = (MobilePhoneFactory) context.getBean("mobilePhoneFactory"); mobilePhoneFactory.testWithin(); System.out.println("-----IPhoneFactory Parent class MobilePhoneFactory Annotations on it@Monitor-----"); IPhoneFactory iPhoneFactory = (IPhoneFactory) context.getBean("iPhoneFactory"); iPhoneFactory.testWithin(); } }
9. Operation results
===============Test within=============== Message from the aspect: within matches to, enhance before method execution Message from the target class FoodFactory: produce food -----I'm the divider----- Message from the aspect: within matches to, enhance before method execution News from the target FoodFactory: selling food to Beijing ===============Test @ within=============== -----Annotation @ Monitor on MobilePhoneFactory----- Message from aspect: @ within matches to, perform enhancement -----The parent class of IPhoneFactory MobilePhoneFactory has the annotation @ Monitor----- Message from aspect: @ within matches to, perform enhancement