Beyond the IOC, AOP is another core of spring. Spring uses AOP to address the separation of application crosscutting concerns (cross-cutting concern) from business logic to decouple. Crosscutting concerns are the same functionality that is scattered across multiple lines of code, such as logs, transactions, security, caches, and so on.
Basic concepts of AOP programming
In OOP, if you want to reuse the same functionality, the general practice is to use inheritance or delegation. Inheritance tends to lead to fragile object systems, which are cumbersome to implement and require complex calls to delegate objects. AOP provides another way of thinking, using AOP we can still define features in one place and tell where to use this feature declaratively. In this way, we can manage and maintain the functions as well as simplify the business logic module so that it pays more attention to its own business logic. In addition, AOP can add new functional behaviors to existing objects.
Terminology of AOP in spring
- Facets (Aspect): Facets define the functionality of crosscutting concerns and the claims that use that functionality. It contains two other terms, notification (Advice, Functional Logic code), and Tangency (Pointcut, Declaration). A facet defines what it is (what) and when and where (When,where) completes its function.
- Notifications (Advice): Notifications define the specific features of a slice and when to use it.
When and when to use? Front (before), back (after), return (after-returning), exception (after-throwing), Surround (Around)
- Tangent point (Pointcut): defines where the function of the facet definition is (where) to function, and looks like it is inserted into the plane from a certain spot. The tangency point should belong to one or more of the connection points.
- Connection point: Defines the timing at which a slice can be applied during the execution of a program, such as before a method call, when the result is returned, when the exception is thrown, and so on, usually one or more of the connection points will be selected as the tangent point for a particular slice.
- Introduction (Introduction): Adding a new method or property to an existing class is called ingestion.
- Weaving (Weaving): Weaving is the process of applying facets to a target object and creating a new proxy object.
There are three ways to weave in:
- Compile time: Requires special compiler support, such as ASPECTJ's weaving compiler
- Class Load period: Special class loader required ClassLoader
- Runtime: Spring AOP uses this method to weave in. An AOP container dynamically creates a proxy object for an object.
Spring's support for AOP
Spring's support for AOP has been much borrowed from AspectJ's approach.
Spring supports four ways of weaving:
- Agent-based classic AOP; (The way is too old, not recommended)
- Pure Pojo facets; (Requires XML configuration)
- @AspectJ annotation-driven facets; (Nothing to say, very useful)
- Injection-type ASPECTJ plane;
- The first three are based on dynamic proxy implementations, so spring's support for AOP is limited to method interception. If the first three types do not meet the requirements (such as blocking constructor methods or field modifications), the fourth type can be used.
- Unlike ASPECTJ, spring's facets are Java classes, Spring uses runtime dynamic proxies, and ASPECTJ needs to learn special syntax to support special compiler weaving.
To select a connection point by using a pointcut
Spring draws on AspectJ's tangent-point expression language. As mentioned earlier, spring is based on dynamic proxies and can only be intercepted on methods, so spring only supports expressions of this level to define.
The ASPECTJ indicators supported by spring are as follows, where the execution to perform the match and the others are the limit matches.
Pointcut expressions More use can refer to official documents
- Spring has added a bean () indicator
Creating slices with annotations
A. Define the slice class and annotate it @Aspect
to mark the class as a facet
Two. Define the method of the slice (what), and use the annotation notation method (when), the available annotations:,,, @Before
@After
(the @AfterReturning
@AfterThrowing
@Around
most powerful, which will be used alone later)
One, two steps after the completion of the code:
@Aspectpublic class Audience{ @Before("execution(** com.xlx.Performance.perform(...))") public void silencephone(){ System.out.println("silencephone"); } @Before("execution(** com.xlx.Performance.perform(...))") public void takeSeats(){ System.out.println("takeSeats"); } @AfterReturning("execution(** com.xlx.Performance.perform(...))") public void applause(){ System.out.println("applause"); } @AfterThrowing("execution(** com.xlx.Performance.perform(...))") public void refund(){ System.out.println("refund"); }}
The cut-off expression in the above code is repeated four times, which is already a repeating code, and the next step is to optimize it.
Three. Defining a @Pointcut
pointcut with annotations
@Aspectpublic class Audience{ //定义切点并修改其他方法重用该切点 @Pointcut("execution(** com.xlx.Performance.perform(...))") public void performance(){ } @Before("performance()") public void silencephone(){ System.out.println("silencephone"); } @Before("performance()") public void takeSeats(){ System.out.println("takeSeats"); } @AfterReturning("performance()") public void applause(){ System.out.println("applause"); } @AfterThrowing("performance()") public void refund(){ System.out.println("refund"); }}
@Aspect
The annotated class is still a generic Java class that can be assembled as a bean
@Beanpublic Audience getAudience(){ return new Audience();}
Four. Use @EnableAspectJAutoProxy
annotations to enable the automatic proxy feature, if it is an XML Config, the corresponding node is<aop:aspectj-autoproxy />
@Configuration@ComponentScan // 包扫描@EnableAspenctJAutoProxy // 启动自动代理public class MyConfig{ // 如果Audience上加了@Component就不需要这个代码了 @Bean public Audience getAudience(){ return new Audience(); }}
Five. Surround notification with surround notification, @Around
@Before
@After
... The following code demonstrates this capability, such as the functionality of the annotated method. If you can use it to record how long the method executes.
@Aspectpublic class Audience{ //定义切点并修改其他方法重用该切点 @Pointcut("execution(** com.xlx.Performance.perform(...))") public void performance(){ } @Around("performance()") public void silencephone(ProcdedingJoinPoint jp){ System.out.println("silencephone"); System.out.println("takeSeats"); try{ // 如果不是刻意为之, 一定要记得调用jp.proceed();否则实际的方法Performance.perform()将会阻塞 jp.proceed(); System.out.println("applause"); }catch(Exception e){ System.out.println("refund"); } }}
Six. Parameter passing, using the tangent-point method in a pointcut expression to args(paramName)
pass parameters to the tangent method
@Aspectpublic class Audience{ //定义切点并修改其他方法重用该切点 @Pointcut("execution(** com.xlx.Performance.perform(int) && args(actornum)))") public void performance(int actornum){ } @Before("performance(actornum)") public void countActor(int actornum){ System.out.println("countActor"+actornum); }}
Referencing new features with annotations
In addition to intercepting the method calls that an object already has, you can use AOP to add new properties and behaviors to the object (introduced). The implementation is implemented by the dynamic proxy generation proxy class.
I. Defining the feature interfaces to add
public interface Encoreable{}
Two. Define the slice (ingest) @Aspect
annotation slice class. @DeclareParents
annotation function Interface static variable
@Aspectpublic class EncoreableIntroducer{ // 可以解释为: 为Performace的所有子类引入接口Encoreable, 并使用默认实现类DefaultEncoreableImpl @DeclareParents(value="xlx.Performace+",defaultImpl=DefaultEncoreableImpl.class) public static Encoreable encoreable;}
Facets based on XML configuration
If there is no way to add annotations to a class, such as without source code, then you have to use XML to configure it.
<aop:config> <aop:aspect ref="aspectBean"> <aop:pointcut id="pcId" expression="execution(** com.xlx.Performance.perform(int) and args(actornum)))" /> <aop:before pointcut-ref="pcId" method="count" /> </aop:aspect></aop:config>
<aop:config> <aop:aspect> <aop:declare-parents type-matching="xlx.Performace+" implement-interface="xlx.Encoreable" delegate-ref="defaultImpl" /> </aop:aspect></aop:config>
AspectJ Injection
Using ASPECTJ injection can solve problems that cannot be solved with dynamic proxies (which should be rare, most applications can be implemented using spring AOP), but need to use the special syntax of ASPECTJ. A well-defined class needs to be configured with XML as a bean, using factory-method="aspectOf"
attributes to formulate how the bean is produced.
<bean factory-method="aspectOf" class="...ClassName"> <property name="other" ref="otherref"/></bean>