What is AOP
(1) Aspect-oriented programming (aspect), the use of AOP can isolate each part of the business logic, so that the coupling degree between the parts of the business logic is reduced, the reusability of the program is improved, and the efficiency of development is improved.
(2) Popular description: Add new functions to the main function without modifying the source code
(3) Use the example of login to illustrate AOP
The role of AOP
Provide declarative transactions: allow users to customize aspects
The following nouns need to be understood:
1. Connection point (JointPoint)
Which methods in the class can be enhanced, these methods are called connection points
2. Entry point (PointCut)
The methods that are actually enhanced are called pointcuts
3. Notification (enhancement) (Advice)
(1) The logical part that is actually enhanced is called notification (enhancement)
(2) There are various types of notifications:
Pre-advice: execute before the method
Post-advice: execute after the method
Surround advice: execute both before and after the method
Exception notification: Execute only when an exception occurs in the method
Final notification: After the method ends, it will be executed no matter what, similar to finally
Notification can be understood as execution, adding code
4. Cross-cutting concerns: methods or functions that span multiple modules of the application. That is, the part that has nothing to do with our business logic, but we need to pay attention to, is the cross-cutting concern. Such as logs, security, cache, transactions, etc...
5. Aspect: A special object whose cross-cutting concerns are modularized. That is, it is a class.
6. Target: The object whose code is added.
7. Proxy (Proxy): The object created after applying the notification to the target object.
Pointcut expression:
execution (public * com.service.impl....(...))
execution (permission modifier, return value type, class full path, method name, parameter list)
1.execution: indicator, execution is the most commonly used indicator, used to match the connection point of method execution.
2.public: access modifier, this parameter is optional.
3. The first * number: the return value type, the number indicates all types, that is, wildcards.
4. Package name: The name of the package to be intercepted. The two dots behind represent the current package and all subpackages of the current package, that is, the com.service.impl package in the example and all classes under the package’s descendants.
5. The second number: the class name, * means all classes.
*(…): method name, * indicates all methods, the parameters in the brackets indicate the parameters of the method, two dots indicate any parameters, optional.
Implementation of spring transactions
first step:
<!--To configure declarative transactions, use spring Inside, it will be injected through the constructor, and a data source needs to be injected <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">--> <bean id="transaction" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="datasource"/> </bean>
Step two:
<!--combine Aop Weaving in business--> <!-- Notifications for configuration transactions--> <tx:advice id="txAdvice" transaction-manager="transaction"> <!-- Prepare to configure transactions for those methods--> <!-- Configure the propagation characteristics of transactions: new propagation There are seven types, generally only one required,Baidu understands--> <tx:attributes> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
third step:
<!-- Configure transaction cut-in aop:pointcut: Target aop:advisor advice-ref: method to inject--> <aop:config> <aop:pointcut id="txPointCut" expression="execution(* com.mybatis.*.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config>
Step Four: Test
@Override public List<Emp> selectAllEmp() { EmpMapper mapper = sqlSession.getMapper(EmpMapper.class); List<Emp> list = mapper.selectAllEmp(); try { Emp emp = new Emp(null, "Linghu Chong", 20, "male", "123@qq.com"); List<Emp> list1 = Arrays.asList(emp); this.addMoreByList(list1); String[] eids={"25","26","27"}; // int a=1/0; this.deleteMoreByArray(eids); } catch (Exception e) { e.printStackTrace(); sqlSession.rollback(); } return list; }
Other examples:
public class DiyPointCut { public void before(){ System.out.println("======pre-method execution========="); } public void after(){ System.out.println("======post method execution========="); } }
public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("added a user"); } @Override public void delete() { System.out.println("deleted a user"); } @Override public void update() { System.out.println("updated a user"); } @Override public void query() { System.out.println("queried a user"); } }
<?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" 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"> <bean id="userService" class="com.tzm.Demo1.UserServiceImpl"></bean> <bean id="log" class="com.tzm.Demo1.log.Log"/> <bean id="afterLog" class="com.tzm.Demo1.log.AfterLog"/> <!--use native spring API accomplish--> <aop:config> <!-- entry point--> <aop:pointcut id="pointcut2" expression="execution(* com.tzm.Demo1.UserServiceImpl.*(..))"/> <!-- Perform Surround Enhancement--> <aop:advisor advice-ref="log" pointcut-ref="pointcut2"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut2"/> </aop:config> <!-- Implemented with a custom class--> <bean id="diyPointcut" class="com.tzm.Demo1.diy.DiyPointCut"></bean> <aop:config> <aop:aspect ref="diyPointcut"> <aop:pointcut id="point" expression="execution(* com.tzm.Demo1.UserServiceImpl.*(..))"/> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config> </beans>
AspectJ framework implements AOP (annotation)
@Before: pre-enhancement
@AfterReturning: post-return enhancement
@Around: surround enhancement
@AfterThrowing: exception enhancement
@After: final enhancement
@Pointcut: Define pointcut
Steps for usage
1.pom.xml
<!--import aspectJ rely--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.20</version> </dependency>
2. Write the enhanced class: UserDao
/** * Proxied object */ public class UserDao { public void add() { // TODO Auto-generated method stub System.out.println("add customer"); } public void delete() { // TODO Auto-generated method stub System.out.println("delete customer"); int i=1/0; } public String find() { // TODO Auto-generated method stub System.out.println("Query customers"); return "fanhuizhi"; } public void update() { // TODO Auto-generated method stub System.out.println("modify customer"); } } 3.use AspectJ Annotation form: ```java /** * NOP Sectional class: the combination of point cutting and enhancement */ @Aspect public class MyAspect { @Before(value = "execution(* com.UserDao.add(..))")//Write expressions here, write which classes need to be added public void before(JoinPoint joinpoint) { System.out.println("Pre-enhancement..."+joinpoint); } @AfterReturning(value = "execution(* com.UserDao.find(..))",returning="returnVal")//Write expressions here, write which classes need to be added public void afterReturning(Object returnVal){ System.out.println("Post Enhancement..."+"method return value"+returnVal); } @Around(value = "execution(* com.UserDao.delete(..))")//Write expressions here, write which classes need to be added public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{ System.out.println("pre-surround enhancement..."); Object obj = proceedingJoinPoint.proceed(); System.out.println("Surround Enhancement..."); return obj; } @AfterThrowing(value = "execution(* com.UserDao.delete(..))",throwing="ex")//Write expressions here, write which classes need to be added public void afterThrowing(Throwable ex) throws Throwable{ System.out.println("No more exceptions..."+ex.getMessage()); } //@After(value = "execution(* com.UserDao.delete(..))")//Write expressions here, write which classes need to be added @After("MyAspect.MyPointCut()")//class name. method name public void after(){ System.out.println("final notice");//No matter if there is any abnormality, it will be notified } //The definition of pointcut is only to define a general expression @Pointcut(value = "execution(* com.UserDao.delete(..))") private void MyPointCut(){ } }
4. Create applicationContext.xml
<!--introduce aop constraints:--> xmlns:aop="http://www.springframework.org/schema/aop" <!-- The bottom layer of automatic proxy generation is AnnotationAwareAspectJautoProxyCreator --> <aop:aspectj-autoproxy/> <bean id="userDao" class="com.UserDao"/> <bean id="MyAspect" class="com.MyAspect"/>
5. Test run