Spring Framework with JDK dynamic proxy CGLib

JDK dynamic proxies and CGLib difference

JDK dynamic proxy: using interceptors (interceptor must implement InvocationHanlder) plus reflection Generates a proxy anonymous class interface
calls before calling InvokeHandler specific method to process.

CGLib dynamic agent: using ASM open source packages, class files proxy object classes loaded in, processed by modifying a subclass bytecode.

When to use JDK and CGLib:

1) If the target object implements the interface, will use the default JDK dynamic proxy AOP implementation case.

2) If the target object implements the interface, you can force the use of CGLIB achieve AOP.

3) If the target object does not implement the interfaces must be used CGLIB library, Spring will automatically switch between JDK dynamic proxies and CGLIB.

How to enforce the use of CGLib achieve AOP:

1) was added CGLIB libraries (aspectjrt-xxx.jar, aspectjweaver-xxx.jar, cglib-nodep-xxx.jar)

2) adding Spring configuration file <aop: aspectj-autoproxy proxy-target-class = "true" />

JDK dynamic proxy CGLib bytecode and generating differences:

1) JDK dynamic proxy class that implements the interface can only build agent, and not for the class.

2) CGLIB is to achieve a proxy for class, mainly generated on the specified class a subclass of these methods cover,
and cover method which achieve enhanced, but because the use of inheritance, it is best not to declare the class or method as final ,
for a final class or method can not be inherited.

How to choose to use Spring JDK or CGLib:

) When implementing an interface Bean, Spring will use the JDK dynamic proxy.

2) When Bean does not implement the interface, Spring use CGlib is achieved.

3) can force CGlib (added in the spring configuration <aop: aspectj-autoproxy proxy-target-class = "true" />)

 

Code testing as follows:

Let's create an interface and class

// interface class 
Package com.zzj.math;

public  interface IMathService {

    int add(int a,int b);
    int div(int a,int b);
    
}

// its class 
Package Penalty for com.zzj.math;

import org.springframework.stereotype.Service;

@Service
public  class MathService implements IMathService {

    @Override
    public int add(int a, int b) {
        return a+b;
    }

    @Override
    public int div(int a, int b) {
        return a/b;
    }
    
}

Then create a proxy class:

package com.zzj.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MethodAop {

    @Before("execution(public int com.zzj.math.MathService.*(..))")
    public void before(JoinPoint jp){
        Signature signature = jp.getSignature();
        System.out.println("The "+signature.getName()+"method begins.");
    }
    
}

in spring xml configuration:

<! - Scan -> 
< context: Scan-Component Base-Package = "com.zzj" > </ context: Component-Scan > 
<! - The target class when true proxy-target-class to create the proxy type, i.e. CGlib agent, or when no write is performed according to a target proxy class interfaces is false, i.e. JDK agent -> 
< AOP: AspectJ the autoproxy- proxy-target-class = "to false" > </ AOP: AspectJ -autoproxy >

 

test:

Default JDK proxy, and need to get the bean must be an interface

package com.zzj.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.zzj.math.IMathService;

public class Test {

    public static void main(String[] args){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        IMathService mathService = applicationContext.getBean (IMathService. Class );
        System.out.println(mathService.getClass());
        applicationContext.close();
    }
}

 

 When forced to use CGLib, we will spring configuration in its corresponding tag xml attribute to true

<aop:aspectj-autoproxy proxy-target-class="true"/>)

Bean acquired test class may be a class may be an interface, the test results are as follows:

 

 

The relationship between two kinds of agents with the target class

CGLib dynamic proxy proxy class objects generated by the target class is a subclass of

System.out.println(mathService.getClass().getSuperclass());

 

JDK dynamic proxy proxy class generated and no inheritance relationship with the target class

Class clazz = mathService.getClass();
Class [] array = clazz.getInterfaces();
for(Class c: array){
    System.out.println(c.getName());
}

 

 

 

AOP implied dynamic proxies
A class method is modified @Transactional annotation, then Spring automatically create a proxy class and its proxy object for the class
We add MathService @Transactional annotation on the class and method configured spring xml file
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

<! - Enable transaction comment -> 
< tx: Annotation-Driven Transaction-Manager = "transactionManager" />

<!--AOP代理-->
<aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>

Test results are as follows:

 

 

 

 
 
 
 

Guess you like

Origin www.cnblogs.com/yimengxianzhi/p/12289598.html