Aspect Oriented Programming AOP

Aspect Oriented Programming

AOP

AOP (Aspect Oriented Programming), that is, aspect-oriented programming, it can be said to OOP (Object Oriented Programming, Object Oriented Programming) added and improved. OOP introduced as encapsulation, inheritance, polymorphism, etc. concept to build a hierarchy of objects, used to simulate the behavior of a common set. However, OOP allows developers to define vertical relationship, but are not suitable for transverse relationship defined, for example, the log function. Log code tends to spread laterally in all object hierarchy, the core object corresponding to the function it no relation to other types of code, such as security, exception handling, and continuity are also transparent so, this spread independent code is referred to throughout the transverse (cross cutting), in OOP design, which led to a lot of code repetition, to the detriment of reusable modules.

Contrary AOP technology, which uses a technique called "transverse", the internal cross-sectional decapsulates the object, and those that affect the behavior of the public classes encapsulated into a plurality of reusable modules, and named it " Aspect ", namely section. The so-called "cut", it simply is that nothing to do with business, but it is the responsibility of the business logic or common module called encapsulated, easy to duplicate code to reduce system and reduce the degree of coupling between modules, and facilitate future operability and maintainability.

Use "cross-cutting" technology, AOP the software system is divided into two parts: core concerns and crosscutting concerns . The main flow of business processes is a core concern, not part of the relationship is with crosscutting concerns. It features a crosscutting concern is that they often occur in many core concerns, and everywhere essentially similar, such as certification authority, log things. AOP is that the various concerns separation system, the core and crosscutting concerns separated.

 

AOP core concepts

1, crosscutting concerns

Intercept of which methods, how to deal with the interception, these concerns called crosscutting concerns

2, section (Aspect)

Class is an abstract object features, is the abstract section of crosscutting concerns

3, the connection point (JoinPoint)

It is intercepted point, because only the supporting method Spring type connection point, the point of attachment in Spring method is to be intercepted, in fact, the point of attachment may also be field or constructors

4, entry point (the pointcut)

Define the connection point of interception

5, the notification (advice)

After the code is called the notification means refers to the connection point of interception to be performed, a notification is divided into front, rear, abnormal end, surrounded by five notifications

6, the target object

Acting audience

7, weaving (Weave)

The cut to the target object and the process leading to the proxy object created

8, is introduced (Introduction)

Under the premise of not modifying code, it may be introduced into the operation of adding methods or dynamic class fields

 

Spring AOP support

Spring AOP proxy in Spring's IOC container is responsible for generation, management, and its dependencies are also responsible for the management by the IOC container . Thus, the AOP agent may be used directly with other bean instance as a target container, this relationship may be provided dependency injection IOC containers. Spring create rules for agents:

1, use Java to create a dynamic proxy AOP proxy by default , so you can create an instance of any of the interfaces that the proxy

2, when the class is not required proxy interface agent, Spring CGLIB will switch to using a proxy , may also be used to force CGLIB

AOP programming is actually very simple thing, look at AOP programming, the programmer need only participate in three parts:

1, the definition of common business components

2, the definition of a starting point, a starting point may cross a plurality of business components

3, the definition enhancement processing, enhancement processing in the operation processing is the frame AOP component is woven into ordinary traffic

So the key is to define the entry points and the definition AOP enhancement processing program, once the entry point and define an appropriate enhancement processing, AOP AOP proxy frame is automatically generated, namely: the proxy object is a proxy object processing method = + enhancement method.

The following gives a Spring AOP .xml file template, called aop.xml, after the contents are expanded on aop.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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
            
</beans>
 

Spring AOP based on the simple realization

Note, before explaining, point: the Spring AOP, since the code to run successfully, only available to developers using Spring jar package is not enough, please add the Internet to download two jar package:

1、aopalliance.jar

2、aspectjweaver.jar

Began to explain with Spring AOP implementations of XML, define an interface:

public interface HelloWorld
{
    void printHelloWorld();
    void doPrint();
}

Interface defines two classes:

 
public class HelloWorldImpl1 implements HelloWorld
{
    public void printHelloWorld()
    {
        System.out.println("Enter HelloWorldImpl1.printHelloWorld()");
    }
    
    public void doPrint()
    {
        System.out.println("Enter HelloWorldImpl1.doPrint()");
        return ;
    }
}
 
 
public class HelloWorldImpl2 implements HelloWorld
{
    public void printHelloWorld()
    {
        System.out.println("Enter HelloWorldImpl2.printHelloWorld()");
    }
    
    public void doPrint()
    {
        System.out.println("Enter HelloWorldImpl2.doPrint()");
        return ;
    }
}
 

Crosscutting concerns, here is the printing time:

 
public class TimeHandler
{
    public void print time ()
    {
        System.out.println("CurrentTime = " + System.currentTimeMillis());
    }
}
 

There are three classes can be achieved with a simple Spring AOP, and look aop.xml configuration:

 
<?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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
        
        <bean id="helloWorldImpl1" class="com.xrq.aop.HelloWorldImpl1" />
        <bean id="helloWorldImpl2" class="com.xrq.aop.HelloWorldImpl2" />
        <bean id="timeHandler" class="com.xrq.aop.TimeHandler" />
        
        <aop:config>
            <aop:aspect id="time" ref="timeHandler">
                <aop:pointcut id="addAllMethod" expression="execution(* com.xrq.aop.HelloWorld.*(..))" />
                <aop:before method="printTime" pointcut-ref="addAllMethod" />
                <aop:after method="printTime" pointcut-ref="addAllMethod" />
            </aop:aspect>
        </aop:config>
</beans>
 

Write a main function call at:

 
public static void main(String[] args)
{
    ApplicationContext ctx = 
            new ClassPathXmlApplicationContext("aop.xml");
        
    HelloWorld hw1 = (HelloWorld)ctx.getBean("helloWorldImpl1");
    HelloWorld hw2 = (HelloWorld)ctx.getBean("helloWorldImpl2");
    hw1.printHelloWorld();
    System.out.println();
    hw1.doPrint ();
    
    System.out.println();
    hw2.printHelloWorld();
    System.out.println();
    hw2.doPrint ();
}
 

Operating results as follows:

 
CurrentTime = 1446129611993
Enter HelloWorldImpl1.printHelloWorld()
CurrentTime = 1446129611993

CurrentTime = 1446129611994
Enter HelloWorldImpl1.doPrint()
CurrentTime = 1446129611994

CurrentTime = 1446129611994
Enter HelloWorldImpl2.printHelloWorld()
CurrentTime = 1446129611994

CurrentTime = 1446129611994
Enter HelloWorldImpl2.doPrint()
CurrentTime = 1446129611994
 

See all methods to achieve two classes to HelloWorld interfaces are added agent, the agent is to print the contents of time

Spring-based AOP uses other details

1, add a cross-cutting concerns, the print log, Java class:

 
public class LogHandler
{
    public void LogBefore()
    {
        System.out.println("Log before method");
    }
    
    public void LogAfter()
    {
        System.out.println("Log after method");
    }
}
 
 
<?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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
        
        <bean id="helloWorldImpl1" class="com.xrq.aop.HelloWorldImpl1" />
        <bean id="helloWorldImpl2" class="com.xrq.aop.HelloWorldImpl2" />
        <bean id="timeHandler" class="com.xrq.aop.TimeHandler" />
        <bean id="logHandler" class="com.xrq.aop.LogHandler" />
        
        <aop:config>
            <aop:aspect id="time" ref="timeHandler" order="1">
                <aop:pointcut id="addTime" expression="execution(* com.xrq.aop.HelloWorld.*(..))" />
                <aop:before method="printTime" pointcut-ref="addTime" />
                <aop:after method="printTime" pointcut-ref="addTime" />
            </aop:aspect>
            <aop:aspect id="log" ref="logHandler" order="2">
                <aop:pointcut id="printLog" expression="execution(* com.xrq.aop.HelloWorld.*(..))" />
                <aop:before method="LogBefore" pointcut-ref="printLog" />
                <aop:after method="LogAfter" pointcut-ref="printLog" />
            </aop:aspect>
        </aop:config>
</beans>
 

The same test class, print the results as follows:

 
CurrentTime = 1446130273734
Log before method
Enter HelloWorldImpl1.printHelloWorld()
Log after method
CurrentTime = 1446130273735

CurrentTime = 1446130273736
Log before method
Enter HelloWorldImpl1.doPrint()
Log after method
CurrentTime = 1446130273736

CurrentTime = 1446130273736
Log before method
Enter HelloWorldImpl2.printHelloWorld()
Log after method
CurrentTime = 1446130273736

CurrentTime = 1446130273737
Log before method
Enter HelloWorldImpl2.doPrint()
Log after method
CurrentTime = 1446130273737
 

To get logHandler used before timeHandler There are two ways:

(1) aspect which has a property order, order number attribute is the order of crosscutting concerns

(2) The logHandler defined previously timeHandler, Spring order to define the default aspect as weaving sequence

2, I just want some method woven into the interface

Modify expression pointcut just fine:

 
<?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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
        
        <bean id="helloWorldImpl1" class="com.xrq.aop.HelloWorldImpl1" />
        <bean id="helloWorldImpl2" class="com.xrq.aop.HelloWorldImpl2" />
        <bean id="timeHandler" class="com.xrq.aop.TimeHandler" />
        <bean id="logHandler" class="com.xrq.aop.LogHandler" />
        
        <aop:config>
            <aop:aspect id="time" ref="timeHandler" order="1">
                <aop:pointcut id="addTime" expression="execution(* com.xrq.aop.HelloWorld.print*(..))" />
                <aop:before method="printTime" pointcut-ref="addTime" />
                <aop:after method="printTime" pointcut-ref="addTime" />
            </aop:aspect>
            <aop:aspect id="log" ref="logHandler" order="2">
                <aop:pointcut id="printLog" expression="execution(* com.xrq.aop.HelloWorld.do*(..))" />
                <aop:before method="LogBefore" pointcut-ref="printLog" />
                <aop:after method="LogAfter" pointcut-ref="printLog" />
            </aop:aspect>
        </aop:config>
</beans>
 

The method represents timeHandler only woven into the beginning of HelloWorld interface to print, logHandler HelloWorld method will be woven into the interface of the beginning do

3, force the use of proxy generation CGLIB

Spring said before the use of dynamic proxy or proxy is generated CGLIB regular, high version of the Spring will automatically select whether to use dynamic proxy or proxy CGLIB generated content, of course, we can force the use of CGLIB generate proxy, that is <aop: config > which has a "proxy-target-class" attribute, if the value is set to true, then the function will be based on the agent class, if the proxy-target-class or is set to false this property is omitted, based on the interface the agency will work

Guess you like

Origin www.cnblogs.com/danxun/p/11750151.html