[Turn] spring of AOP principle, using what scene?

What is AOP

AOP (Aspect-OrientedProgramming, aspect-oriented programming), can be said to OOP (Object-Oriented Programing, object-oriented programming) added and improved. OOP concepts introduced encapsulation, inheritance, and polymorphism to establish a hierarchy of objects, to simulate a set of behaviors common. When we need to introduce a common behavior for scattered objects, OOP look powerless. In other words, OOP allows you to define the relationship between a top-down, but it does not fit the definition of the relationship from left to right. Such as logging. Log code tends to spread at all levels of the object hierarchy, the core function of the object to which it spread no relation. For other types of code, such as security, exception handling, and continuous transparent as well. Such scattered across unrelated code is called transverse (cross-cutting) code in OOP design, which led to a large number of duplicate code reuse detriment of each module.

 

AOP technology while on the contrary, it 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 the name for the "aspect", that is respect. The so-called "respect", simply put, is unrelated to those with business, but as a logical or liability business modules together called encapsulated, easy to duplicate code to reduce system and reduce the degree of coupling between modules, and facilitate future may operability and maintainability. AOP is represented by a transverse relationship, if the "subject" is a hollow cylinder, wherein the package is the attributes and behavior of the object; the method aspect-oriented programming, as if a razor, the cross section of these hollow cylinder apart to obtain its message inside. The cut-away section, the so-called "respect" the. Then it won the day with clever work Cherish these cut-away section recovery, leaving no trace.

 

Use "cross-cutting" technology, AOP the software system is divided into two parts: the 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 similar. Such as certification authority, logging, transaction processing. Aop effect separation of concerns is that the various systems, the core and crosscutting concerns separated. As Avanade's senior solutions architect Adam Magee said, AOP is the core idea of ​​"the application business logic with the separation of its support universal service."

 

AOP implementation technology, divided into two categories: one is dynamic agent technology, the use of the embodiment intercepted message, the message decorated, instead of performing the original object behavior; second static weaving manner, the introduction of a specific syntax to create "aspect", so that the compiler can be woven into the code related to "aspect" during compilation.


AOP usage scenarios

AOP crosscutting concerns for packaging, can be used specifically in the following scenarios:

 

Authentication Permissions

Caching Cache

Context passing content delivery

Error handling Error handling

Lazy loading lazy loading

Debugging Debugging

logging, tracing, profiling and monitoring recording tracks Picture

Performance optimization performance optimization

Persistence Persistence

Resource pooling resources pool

Synchronization Synchronization

Transactions Transaction


AOP concepts

Aspect (Aspect): a modular point of interest, this concerns the implementation might otherwise cut across multiple objects. J2EE application transaction management is a good example of cross-cutting concerns. Terms of use spring to achieve the Advisor or interceptors.

 

Connection point (Joinpoint): during program execution definite point, such as calling or particular exception being thrown.

 

Notification (Advice): In a particular connection point, an operation performed AOP framework. Various types of notification includes "around", "before" and "throws" notification. The type of notification will be discussed below. Many AOP frameworks, including Spring, model an advice as an interceptor, maintaining a "around" the interceptor chain connection points. Spring defines four advice: BeforeAdvice, AfterAdvice, ThrowAdvice and DynamicIntroductionAdvice

 

Entry point (Pointcut): Specifies a notification of a collection of point of attachment will be initiated. AOP framework must allow developers to specify the starting point: for example, using regular expressions. Spring Pointcut defined interfaces, and for combining MethodMatcher ClassFilter, can be clearly understood by name, MethodMatcher method is used to check whether the target class may be applied to this notice, and is used to check whether ClassFilter should be applied to the target class Pointcut on

 

Introducing (Introduction): or a method of adding a field to the class to be notified. Spring allows the introduction of new interfaces to any object to be notified. For example, you could use an introduction to make any object that implements IsModified interface to simplify cache. Spring Introduction to be used, there can be realized by DelegatingIntroductionInterceptor notification, and to configure the proxy class interfaces Advice be achieved by DefaultIntroductionAdvisor

 

Audience (Target Object): comprising a connection point objects. Also referred to as advised or proxy object. POJO

 

AOP proxy (AOP Proxy): Object created by the AOP framework, including notification. In Spring, AOP proxy will be a JDK dynamic proxy or proxy CGLIB.

 

Weaving (Weaving): assembling aspects to create an advised object. This can be done at compile time (e.g. using AspectJ compiler), it may be done at runtime. Spring and other purely the Java  AOP frameworks, performs weaving at runtime.


Spring AOP Components

This class diagram shows the following Spring main components of AOP


How to use Spring AOP


Spring AOP may be used by a configuration file or programming.

 

Configuration can be done via xml file, there are about four ways:

1.         Configuration ProxyFactoryBean, explicitly set advisors, advice, target, etc.

2. Configure AutoProxyCreator, in this way, is still the same as before using the defined bean, but obtained from the container is already a proxy object

3. By: configuring <aop config>

4 by: configuring <aop aspectj-autoproxy>, the use of annotation and notification to identify AspectJ pointcut

 

May be directly used to programmatically ProxyFactory the Spring AOP, the target object may be provided, Advisor like configuration provided by the methods ProxyFactory ultimately acquires proxy object The getProxy () method

 

Examples of specific uses can google. Omitted here


Spring AOP proxy object generated


Spring provides two ways to generate a proxy object: JDKProxy and Cglib, generated according to the configuration determined by AopProxyFactory AdvisedSupport object which way the specific use. The default strategy is if the target class is an interface, use JDK dynamic proxy technology, otherwise use Cglib to generate a proxy. Let's look at how to use Spring JDK to generate a proxy object, to generate specific code in JdkDynamicAopProxy this class, directly on the relevant code:

     / **  
        * <OL> 
        * <Li> Get proxy class interfaces to be achieved, in addition to the configuration Advised object, will be added SpringProxy, Advised (= opaque to false) 
        * <Li> Check the interface obtained above there or interfaces define equals hashcode 
        * <li> call Proxy.newProxyInstance create a proxy object 
        * </ OL> 
        * /   
       public Object the getProxy (ClassLoader classLoader) {  
            IF (logger.isDebugEnabled ()) {   
               logger.debug ( "creating the JDK Dynamic proxy : IS target Source "+ the this .advised.getTargetSource ());   
           }   
           Class [] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces ( the this .advised);   
           findDefinedEqualsAndHashCodeMethods (proxiedInterfaces);  
           return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);  
    }  

 

That this is very clear, the comments I have also written clearly, and not repeat them.

 

The following question is, proxy objects are generated, how it is woven into the section?

We know InvocationHandler core JDK dynamic proxy method generated proxy object invocation delegate to InvocationHandler.invoke () method. The signature by JdkDynamicAopProxy we can see that this class actually implements InvocationHandler, Here we have analyzed invoke () method in this class to achieve a specific look at how Spring AOP is woven into facets.

      public Object invoke(Object proxy, Method method, Object[] args) throwsThrowable {  
           MethodInvocation invocation = null;  
           Object oldProxy = null;  
           boolean setProxyContext = false;  
       
           TargetSource targetSource = this.advised.targetSource;  
           Class targetClass = null;  
           Object target = null;  
       
           try {  
               //eqauls()方法,具目标对象未实现此方法  
               if (!this&& .equalsDefined AopUtils.isEqualsMethod (Method)) {  
                     return (the equals (args [0])? of Boolean.TRUE: Boolean.FALSE The);   
               }   
       
               // the hashCode () method, this method has not achieved the target object   
               IF ! ( the this . && hashCodeDefined AopUtils.isHashCodeMethod (method)) {  
                     return newInteger (the hashCode ());   
               }   
       
               // the Advised interface or interfaces defined in the parent method, a direct reflective call, the application does not notice   
               IF (! the this .advised.opaque && method. The getDeclaringClass (). isInterface ()  
                         && method.getDeclaringClass (). IsAssignableFrom (the Advised. class)) {  
                    // Service invocations onProxyConfig with the proxy config...  
                    return AopUtils.invokeJoinpointUsingReflection(this.advised,method, args);  
               }  
       
               Object retVal = null;  
       
               if (this.advised.exposeProxy) {  
                    // Make invocation available ifnecessary.  
                    oldProxy = AopContext.setCurrentProxy(proxy);  
                    setProxyContext = true;  
               }  
       
               //获得目标对象的类  
               target =targetSource.getTarget ();  
                IF (target =! null ) {   
                    targetClass = target.getClass ();   
               }   
       
               // Get the list may be applied to the method Interceptor   
               List catena alberghiera = the this .advised.getInterceptorsAndDynamicInterceptionAdvice (Method, targetClass);   
       
               / / If there is no notification may be applied to this method (Interceptor), this call directly reflected Method.invoke (target, args)   
               IF (chain.isEmpty ()) {   
                    retVal = AopUtils.invokeJoinpointUsingReflection (target, method, args);   
               } the else {  
                     //创建MethodInvocation  
                    invocation = newReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);  
                    retVal = invocation.proceed();  
               }  
       
               // Massage return value if necessary.  
               if (retVal != null && retVal == target &&method.getReturnType().isInstance(proxy)  
                        && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {  
                    // Special case: it returned"this" and the return type of the method  
                    // is type-compatible. Notethat we can't help if the target sets  
                    // a reference to itself inanother returned object.  
                    retVal = proxy;  
               }  
               return retVal;  
           } finally {  
               if (target != null && !targetSource.isStatic()) {  
                    // Must have come fromTargetSource.  
                   targetSource.releaseTarget(target);  
               }  
               if (setProxyContext) {  
                    // Restore old proxy.  
                    AopContext.setCurrentProxy(oldProxy);  
               }  
           }  
        }  

 

 

Brief description of the main flow may: obtaining notification may be applied to the method of the chain (Interceptor Chain), if so, notifies the application, and performs JoinPoint; if not, then execution directly reflected joinpoint. The key here is how to inform the chain is obtained and how it is carried out, one by one under analysis below.

 

First of all, you can see from the above code, the notification chain is to get through Advised.getInterceptorsAndDynamicInterceptionAdvice () this method, we look at the implementation of this method:

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class targetClass) {  
    MethodCacheKeycacheKey = new MethodCacheKey(method);  
    List<Object> cached = this.methodCache.get(cacheKey);  
    if(cached == null) {  
        cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this,method, targetClass);  
        this.methodCache.put(cacheKey, cached);  
    }  
    return cached;  
}  

 

 

You can see the actual acquisition work is actually done by AdvisorChainFactory. GetInterceptorsAndDynamicInterceptionAdvice () this method, to obtain the results are cached.

To analyze the following methods to achieve this:

 

   / **  
     * obtained from the provided configuration example config advisor list traversal process the advisor. If an IntroductionAdvisor, 
     * the Advisor determines whether this is applied to the target class targetClass. If PointcutAdvisor, it is determined 
     * This application can Advisor the target method to method. Advisor by satisfying the condition list Back AdvisorAdaptor converted to Interceptor. 
     * /   
    public list getInterceptorsAndDynamicInterceptionAdvice (config the Advised, Methodmethod, Class targetClass) {  
         // This iS Somewhat Tricky ... WE have have to Introductions Process First,  
         // . But WE need to preserve the Order in at The Ultimate List   
        List interceptorList = new new ArrayList (config.getAdvisors () length.);   

        // see if included IntroductionAdvisor   
        boolean hasIntroductions = hasMatchingIntroductions(config,targetClass);  

        //这里实际上注册一系列AdvisorAdapter,用于将Advisor转化成MethodInterceptor  
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();  

        Advisor[] advisors = config.getAdvisors();  
        for (int i = 0; i<advisors.length; i++) {  
            Advisor advisor = advisors[i];  
            if (advisor instanceof PointcutAdvisor) {  
                // Add it conditionally.  
                PointcutAdvisor pointcutAdvisor= (PointcutAdvisor) advisor;  
                IF (config.isPreFiltered () || {pointcutAdvisor.getPointcut () getClassFilter () The matches (targetClass)..)  
                     // the TODO: the location of this place these two methods can be used interchangeably  
                     // be converted to Advisor Interceptor   
                    MethodInterceptor [ ] = interceptors registry.getInterceptors (advisor);   

                    // check whether the current advisor pointcut matches the current method   
                    MethodMatcher mm = pointcutAdvisor.getPointcut () getMethodMatcher ();.   

                    iF (MethodMatchers.matches (mm, method, targetClass, hasIntroductions)) {  
                         IF (mm.isRuntime ()) {  
                             // Creating a newobject instance in the getInterceptors() method  
                            // isn't a problemas we normally cache created chains.  
                            for (intj = 0; j<interceptors.length; j++) {  
                                interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptors[j], mm));  
                            }  
                        } else {  
                            interceptorList.addAll(Arrays.asList(interceptors));  
                        }  
                    }  
                }  
            } else if (advisor instanceof IntroductionAdvisor){  
                IntroductionAdvisor ia = (IntroductionAdvisor) advisor;  
                if(config.isPreFiltered() || ia.getClassFilter().matches(targetClass)) {  
                    Interceptor[] interceptors = registry.getInterceptors(advisor);  
                    interceptorList.addAll(Arrays.asList(interceptors));  
                }  
            } else {  
                Interceptor[] interceptors = registry.getInterceptors(advisor);  
                interceptorList.addAll(Arrays.asList(interceptors));  
            }  
        }  
        return interceptorList;  
    }  

 

 

After completion of the implementation of this method, Advised Advisor configuration can be applied to the connection point of the target class, or totally converted into MethodInterceptor.

 

Next we get a look at how the interceptor chain is functioning.

 

    if (chain.isEmpty()) {  
        retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);  
    } else {  
        //创建MethodInvocation  
        invocation = newReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);  
        retVal = invocation.proceed();  
    } 

       

         As can be seen from this code, if the resulting interceptor chain is empty, the target method is called direct reflection, otherwise create MethodInvocation, proceed to call its methods, trigger the execution of the interceptor chain, look at the specific code

public Object proceed() throws Throwable {  
    //  We start with an index of -1and increment early.  
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size()- 1) {  
        //如果Interceptor执行完了,则执行joinPoint  
        return invokeJoinpoint();  
    }  

    Object interceptorOrInterceptionAdvice =  
            this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);  

    //如果要动态匹配joinPoint  
    if (interceptorOrInterceptionAdvice instanceofInterceptorAndDynamicMethodMatcher) {  
         // the Evaluate Matcher here Wallpaper Dynamic Method: Part static Will have have already  
         // been EVALUATED external and found to match.   
        InterceptorAndDynamicMethodMatcher DM =   
                (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;   
        // dynamic adaptation of: run-time parameter satisfies the matching condition   
        IF (dm.methodMatcher .matches ( the this .method, the this .targetClass, the this .arguments)) {  
             // implementation of the current Intercetpor   
            returndm.interceptor.invoke ( the this );   
        }   
        the else {  
             //Dynamic matching fails, the current skip Intercetpor, the next call Interceptor   
            return the proceed ();   
        }   
    }   
    the else {  
         // It Interceptor apos AN, SO WE Just Invoke IT: of The pointcutwill have have  
         // been statically before the this Object WAS EVALUATED external Constructed.  
         / / execution of the current Intercetpor   
        return ((MethodInterceptor) interceptorOrInterceptionAdvice) .invoke ( the this );   
    }   
}

Reprinted: https: //blog.csdn.net/wuruijiang/article/details/78970720.

Guess you like

Origin www.cnblogs.com/day1day1up/p/11129576.html