catalogue
1, Pure annotation development
3. Create a notification class and define notification methods
4. Create Spring core configuration class
preface
The method of configuring AOP with xml is a little troublesome. In enterprise development, most of them are developed with annotations, which is a lever of efficiency. If you need to know how to configure AOP based on xml, go to the previous article!
Tip: the following is the main content of this article. The following cases can be used for reference
1, Pure annotation development
- In fact, annotation development is to eliminate the Spring configuration file and use annotation to replace what is done in the configuration file
- In the xml configuration file, we need to create the notification class and target class with the < bean > tag, and then hand them over to the IOC container of Spring for management. Then configure AOP
2, Operation steps
1. Import dependency
The code is as follows (example):
<dependencies> <!--Spring Context core package--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.2.RELEASE</version> </dependency> <!--AOP Implementation package for--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> <!--Spring Integration with unit test--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.1.2.RELEASE</version> </dependency> <!--unit testing --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies>
2. Create the target interface, define the abstract method, implement the implementation class of the target interface, and rewrite the method (target method)
The code is as follows (example):
/** * @Author:Yan * @Date 2022/01/21 20:07 * @Description Target interface **/ public interface Target { String getName(String name); }
/** * @Author:Yan * @Date 2022/01/21 20:08 * @Description Implementation class of target interface **/ //@The Component annotation is equivalent to using < bean >, which means that the object of the class is created and handed over to the IOC container for management @Component public class TargetImpl implements Target { @Override public String getName(String name) { System.out.println("Target method...."+name); return name; } }
3. Create a notification class and define notification methods
The code is as follows (example):
/** * @Author:Yan * @Date 2022/01/21 19:56 * @Description 3,Create a notification class and define notification methods * 1,The notification class uses @ Aspect to indicate that the class is an Aspect class, and uses @ Component annotation to indicate that the object of this class is created and handed over to Spring for management * 2,Defining a method and annotating it with @ Pointcut("pointcut expression") makes no sense * 3,Method uses @ notification type ("method ming()" of pointcut expression) **/ @Aspect //Indicates that the square class is a section class @Component public class MyAdvice { //2. Define a method and annotate it with @ Pointcut("pointcut expression") @Pointcut("execution(* com.itheima..*.*(..))") public void pointcut() { } //3. Method uses the @ notification type @Before("pointcut()") public void before() { System.out.println("Before advice -->Print log"); } @After("pointcut()") public void after() { System.out.println("Final notice-->Print log"); } @AfterReturning("pointcut()") public void afterRun() { System.out.println("Notify on return-->Print log"); } @AfterThrowing("pointcut()") public void afterThrow() { System.out.println("After throwing advice -->Print log"); } @Around("pointcut()") public Object around(ProceedingJoinPoint pjp) throws Throwable { //Gets the parameters of the target method pjp.getArgs()[0] = "Li Si"; System.out.println("Around Advice -->Print log"); //Pass back the set target method parameters Object proceed = pjp.proceed(pjp.getArgs()); //And return. If not, the received return value is null return proceed; } }
4. Create Spring core configuration class
/** * @Author:Yan * @Date 2022/01/21 20:09 * @Description Core configuration class * 1,Use @ Configuration to indicate that this class is a core Configuration class * 2,Use @ ComponentScan("path to package") to indicate that annotation scanning is turned on * 3,Use @ EnableAspectJAutoProxy to start AOP annotation scanning **/ @Configuration //Indicates that this class is the Spring core configuration class @ComponentScan("com.itheima") //Enable annotation scanning @EnableAspectJAutoProxy //Indicates that the AOP annotation driver is enabled public class AppConfig { }
5. Testing
/** * @Author:Yan * @Date 2022/01/21 20:14 * @Description Test pure annotation **/ @RunWith(SpringJUnit4ClassRunner.class) //Represents this type of test class @ContextConfiguration(classes = AppConfig.class) public class textAnno { //Define the attribute of the target class and inject data into the attribute using the @ Autowiredr annotation @Autowired private Target target; @Test public void method() { //Call method String name = target.getName("Zhang San"); System.out.println(name); } }
6. Test results
Around Advice -->Print log Before advice -->Print log Target method....Li Si Final notice-->Print log Notify on return-->Print log Li Si
3, Note explanation:
- @ Aspect: this annotation acts on a class, indicating that the class is an Aspect class. Replace < AOP: Aspect ref = "notification class unique ID" > in xml method
-
@ Component: this annotation acts on a class. It is used to create objects of this class and submit them to the IOC container for management, replacing the < bean > tag in xml mode
-
@Pointcut("execution ="): this annotation acts on the method. The current method name is used as the pointcut reference name. The method is meaningless. The execution attribute is used to define the pointcut expression. Replace < AOP: pointcut id = "" expression = "execution (pointcut expression)" / >
-
@Before("pointcut method name ()"), @ After("pointcut method name ()"), @ AfterReturning("pointcut method name ()"), @ AfterThrowing("pointcut method name ()"), @ Around("pointcut method name ()"): these annotations act on the method, indicate what notification type the method belongs to, and specify the pointcut expression.
-
@Configuration: this annotation is applied to a class, indicating that the class is a Spring core configuration class. It is generally used on configuration classes
-
@ComponentScan("com.itheima") this annotation acts on the class, indicating that Spring annotation scanning is enabled. It is generally used on configuration classes
-
@EnableAspectJAutoProxy , this annotation acts on the class, indicating that the AOP annotation driver is enabled. It is generally used on configuration classes
-
@RunWith(SpringJUnit4ClassRunner.class) this annotation acts on the class and represents the test class of the class.
-
@ContextConfiguration(classes = AppConfig.class) this annotation acts on the class and is used to read the Spring configuration file. Instead of xml, you need to create factory objects
4, Precautions:
-
If the method in a class is enhanced by AOP, the proxy object of the class is managed in the SpringIOC container.. the proxy object type is not the implementation class type but belongs to the interface type, so after using AOP, a bean object is obtained through the interface type.. it cannot be obtained through the implementation class type. As long as a method in the class is enhanced by AOP, SPR exists The bean object in the ing IOC container is a proxy object. You must use the interface type to get and receive
-
When defining surround enhancement, you need to set the method parameters. If you don't set its function, it is equivalent to pre enhancement
When the parameter is not set, the surround notification is executed instead of the pre notification
Use the ProceedingJoinPoint to obtain the method parameter and re assign the value , modify the parameter , you need to pass the parameter to the target method
proceed(): call the target method to execute. If there are parameters, they will be passed in parentheses
The surround notification can modify the return value of the target method by using the ProceedingJoinPoint, so the surround notification method needs to have a return value