Scope of AOP
AOP is section-oriented programming, and we can propose as separate modules that do not intersperse the whole project, such as logging, permissions, etc., but are not core logical functions
AspectJ-AOP
AOP is already available in Spring in Java, so you can create an Aspect directly in idea. Note that the keyword is Aspect (myAspectjdemo. aj, where aj is the suffix of AspectJ), meaning the same as class, which defines an AspectJ class. AspectJ is a Java implementation of an AOP framework that enables AOP compilation of Java code (typically at compile time) and gives Java code AspectJ’s AOP capabilities (requiring a special compiler, of course). AspectJ is arguably the most mature AOP framework currently implemented. The most feature-rich language, and fortunately, AspectJ is fully compatible with Java programs, almost seamlessly.
Public class HelloWord{public void sayHello{system.out.println ("hello"); } public static void main(String args[]){ HelloWord hello=new HelloWord(); hello.sayHello(); }}Copy the code
Pointcut recordLog(): Call (* helloWord.sayHello (..)) ); /** * pointcut authCheck(): Call (* helloword.sayHello (..)) ); /** * define pre-notification! */ before():authCheck(){
System.out.println("Verify permission before sayHello method executes"); } /** * define after notification */ after():recordLog(){
System.out.println("Log sayHello method after execution"); }}Copy the code
Results the figure
pointcut authCheck():call(* HelloWord.sayHello(..) )
The keyword is pointcut, which defines the pointcut point, followed by the function name, and then writes the matching expression. The function is usually matched using call() or execution().
The pointcut function name: match expression
RecordLog () is the function name, custom, * denotes any return value, followed by the target function to intercept, sayHello(..) The.. Represents any parameter type. Use pointcut to define a recordLog pointcut function that intercepts the sayHello method of the HelloWord class with any parameters
before():authCheck(){ System.out.println(“something”); }
Before the method before the function name becomes the notification method, and there are five notification methods
- Before The target method is executed before it is notified
- After The target method is executed after execution, followed by notification
- Executed when the After RETURNING target method returns, with post-return notification
- The After Throwing target method performs exception notification when it throws an exception
- Around is executed in the execution of the object function, controlling whether the object function is executed or not, and surrounding the notification
Pointcut aspect weaving into point and other concepts
Weave into simple principles and processes
Weaving is simply how to apply AspectJ to the target function. This process is generally divided into dynamic weaving and static weaving. Dynamic weaving is the way that the code to be enhanced is dynamically woven into the target class at run time. The underlying implementation is reflection) or CGLIB’s dynamic proxy (underlying implementation is inheritance). SpringAOP uses runtime enhanced proxy techniques, which will be discussed later, with a focus on static weaving, which ApectJ uses. ApectJ mainly uses compile-time weaving, in which AspectJ’s ACJ compiler (similar to JavAC) is used to compile aspect classes into class bytecode and then at Java target class compilation time, that is, compile the aspect classes first and then the target classes.
In the Spring AOP
Spring AOP has the same goal as ApectJ in addressing crosscutting business uniformly, but unlike AspectJ, Spring AOP does not attempt to provide full AOP functionality (even if it is fully implementable), Spring AOP is more focused on integration with the Spring IOC container and combining that strength to address crosscutting business issues, so AspectJ has a significant advantage over AOP in terms of full functionality.
At the same time, Spring has noticed that AspectJ relies on a special compiler (ajC compiler) for the way AOP is implemented, so Spring wisely sidesteps this and turns to the implementation principles of dynamic proxy technology to build Spring AOP’s internal mechanisms (dynamic weaving). This is the most fundamental difference from AspectJ (static weaving). The development of the annotation style in the @aspect form was introduced after AspectJ 1.5, and Spring followed this approach very quickly, so Spring 2.0 uses the same annotations as AspectJ.
Note that Spring only uses the same annotations as AspectJ 5, but it still doesn’t use AspectJ’s compiler. The underlying implementation is dynamic proxy technology, so it doesn’t rely on AspectJ’s compiler. Let’s start with a simple example to demonstrate the use of AOP in Spring
Public interface UserDao {int addUser(); void updateUser(); void deleteUser(); void findUser(); } / / implementation class import com. Zejian. Spring. SpringAop. Dao. UserDao; import org.springframework.stereotype.Repository; /** * Created by zejian on 2017/2/19. * Blog: http://blog.csdn.net/javazejian [the original address, please respect the original] * / @ Repository public class UserDaoImp implements UserDao {@ Override public intaddUser() {
System.out.println("add user ......");
return 6666;
}
@Override
public void updateUser() {
System.out.println("update user ......");
}
@Override
public void deleteUser() {
System.out.println("delete user ......");
}
@Override
public void findUser() {
System.out.println("find user ......"); }}Copy the code
/** * public class MyAspect {/** *"execution(* com.zejian.spring.springAop.dao.UserDao.addUser(..) )")
public void before(){
System.out.println("Pre-notification...."); } /** * after notification *returnVal, return value */ @afterreturning (value="execution(* com.zejian.spring.springAop.dao.UserDao.addUser(..) )",returning = "returnVal")
public void AfterReturning(Object returnVal){
System.out.println("Post notification...."+returnVal); } /** * wrap around the notification * @param joinPoint can be used to implement the pointcut class * @return
* @throws Throwable
*/
@Around("execution(* com.zejian.spring.springAop.dao.UserDao.addUser(..) )")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Surround notification before....");
Object obj= (Object) joinPoint.proceed();
System.out.println("Surround notification after....");
returnobj; } /** * throw notification * @param e */ @afterthrowing (value="execution(* com.zejian.spring.springAop.dao.UserDao.addUser(..) )",throwing = "e")
public void afterThrowable(Throwable e){
System.out.println("Error: MSG ="+e.getMessage()); } /** * the method that will be executed in any case */ @after (value="execution(* com.zejian.spring.springAop.dao.UserDao.addUser(..) )")
public void after(){
System.out.println("Final notice...."); }}Copy the code
// The configuration file to the Spring IOC container to manage <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">
<!-- 启动@aspectj的自动代理支持,这里开着可以使用Aspect的注解功能-->
<aop:aspectj-autoproxy />
<!-- 定义目标对象 -->
<bean id="userDaos" class="com.zejian.spring.springAop.dao.daoimp.UserDaoImp"/ > <! Define the aspect class --> <bean name="myAspectJ" class="com.zejian.spring.springAop.AspectJ.MyAspect"/>
</beans>
Copy the code
/ / test class @ RunWith SpringJUnit4ClassRunner. Class @ ContextConfiguration (locations ="classpath:spring/spring-aspectj.xml")
public class UserDaoAspectJ {
@Autowired
UserDao userDao;
@Test
public void aspectJTest(){ userDao.addUser(); }}Copy the code
Annotation-based Spring AOP development
- Defining pointcuts Development pointcuts are defined in the form described above, using
@After(value="execution(* com.zejian.spring.springAop.dao.UserDao.addUser(..) )")
public void after(){
System.out.println("Final notice....");
}
Copy the code
You can also use Pointcut pointcuts similar to AspectJ
/** * @pointcut ("execution(* com.zejian.spring.springAop.dao.UserDao.addUser(..) )")
private void myPointcut(){} /** * apply the pointcut function */ @after (value=)"myPointcut()")
public void afterDemo(){
System.out.println("Final notice....");
}
Copy the code
- Pointcut designators SpringAOP provides matching expressions, also known as pointcut designators, for method advice to be applied to the target method of the corresponding filter
-
Wildcard characters (including *,.. , +)
- . Represents any number of parameters in the method definition, in addition to any number of packages in the class definition
// Execution of a public method with any return value, name, or argument (public * *(..)) // Match all methods in all classes within the com.zejian.dao package and its subpackages. *)Copy the code
- + means match any subclass of the given class
//匹配实现了DaoUser接口的所有子类的方法 within(com.zejian.dao.DaoUser+) Copy the code
- * matches any number of characters
// Match all methods within(com.zejian.service.. *) // Match withsetAt the beginning, the argument is of type int and any return value is execution(*)set*(int)) Copy the code
- . Represents any number of parameters in the method definition, in addition to any number of packages in the class definition
-
Type signature expressions To facilitate type (interface, class name, package name) filtering methods, Spring AOP provides the within keyword. The syntax is as follows
within ()
That is, followed by the package name or class name
// Matches all methods in all classes in the com.zejian.dao package and its subpackages @pointcut ("within(com.zejian.dao.. *)"// Match all methods in UserDaoImpl @pointcut ("within(com.zejian.dao.UserDaoImpl)"// Match all methods @pointcut in UserDaoImpl class and its subclasses"within(com.zejian.dao.UserDaoImpl+)"// Match all methods of all classes implementing the UserDao interface @pointcut ("within(com.zejian.dao.UserDao+)") Copy the code
-
Method signature expression
//scope: method scope, such as public,private,protect //returnt-type: method return value type //fully qualified-class-name: // Parameters method execution(<scope> <)return-type> <fully-qualified-class-name>.*(parameters)) Copy the code
-
Other indicators @bean,@this,@target,@within,@annotation
-
Pay attention to
After @aspect support is enabled in the configuration file, the Spring container will only attempt to automatically recognize beans with @aspect, provided that any defined Aspect classes have been declared as beans in the configuration file.
<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=""-- > <! Aop: Aspectj-autoproxy /> <! Define the target object --> <bean id="userDaos" class="com.zejian.spring.springAop.dao.daoimp.UserDaoImp"/ > <! Define the aspect class --> <bean name="myAspectJ" class="com.zejian.spring.springAop.AspectJ.MyAspect"/>
<bean name="aspectOne" class="com.zejian.spring.springAop.AspectJ.AspectOne" />
<bean name="aspectTwo" class="com.zejian.spring.springAop.AspectJ.AspectTwo" />
</beans>
Copy the code