This article has participated in the third “topic writing” track of the Denver Creators Training Camp. For details, check out: Digg Project | Creators Training Camp third is ongoing, “write” to make a personal impact.


πŸ˜‰ offer yourself

Self-introduction, to everyone recommend their column 😁, welcome small partners to collect attention 😊

MybatisPlus column

App crawler Column

PC side crawler column

Big factory interview question column


✨ What is the difference between the two

Jdk dynamic proxy: Use the interceptor (must implement the InvocationHandler interface) and reflection mechanism to generate a proxy interface anonymous class, before calling the specific method to call the InvokeHandler to handle

2, Cglib dynamic proxy: using the ASM framework, load the class file generated by the proxy object class, and modify its bytecode generation subclass to proxy

So:

If you want to implement JDK dynamic proxies, the proxy class must implement the interface, otherwise it cannot be used;

If you want to use a CGlib dynamic proxy, the proxy class cannot use final modifier classes and methods;

There are: In jdk6 has, jdk7, jdk8 gradually the JDK dynamic proxy after optimization, the call number is less, the JDK efficiency is higher than the additional agency efficiency, only when a large number of calls, jdk6 has and jdk7 than additional agent efficiency is lower, but by jdk8, The JDK agent is more efficient than the CGLIB agent.



🌈 How to implement

β˜€JDK dynamic proxy

UserService interface

public interface UserService {

    void addUser(a);

    void updateUser(String str);

}
Copy the code

UserServiceImpl implementation class

public class UserServiceImpl implements UserService {
    @Override
    public void addUser(a) {
        System.out.println("Add user");
    }

    @Override
    public void updateUser(String str) {
        System.out.println("Update user information"+ str); }}Copy the code

The UserProxy proxy class implements the InvocationHandler interface to override the Invoke method

public class UserProxy implements InvocationHandler {


    private Object target;

    public UserProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Object res = method.invoke(target, args);

        System.out.println("Log");

        returnres; }}Copy the code

The test test class

public class test {


    public static void main(String[] args) {

        UserServiceImpl impl = new UserServiceImpl();
        UserProxy userProxy = new UserProxy(impl);
        UserService userService = (UserService) Proxy.newProxyInstance(impl.getClass().getClassLoader(),impl.getClass().getInterfaces(),userProxy);
        userService.addUser();
        userService.updateUser("I'm a shrimp."); }}Copy the code

Visibility is enhanced to print out logging



β˜€CGlib dynamic proxy

Unlike JDK dynamic proxies, CGlib requires importing Jar packages, so I used SpringBoot to import the dependencies directly

At this time, Teacher Ma came out silently said:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>
Copy the code

UserServiceImpl Proxied class

public class UserServiceImpl {

    public void addUser(a) {
        System.out.println("Added a user");
    }

    public void deleteUser(a) {
        System.out.println("Deleted a user"); }}Copy the code

UserServiceCGlib agent

public class UserServiceCGlib implements MethodInterceptor {


    private Object target;

    public UserServiceCGlib(a) {}public UserServiceCGlib(Object target) {
        this.target = target;
    }

    // Return a proxy object: the proxy object of the target object
    public Object getProxyInstance(a) {
        1. Create a utility class
        Enhancer enhancer = new Enhancer();
        //2. Set the parent class
        enhancer.setSuperclass(target.getClass());
        // set the callback function
        enhancer.setCallback(this);
        //4. Create subclass objects, that is, proxy objects
        return enhancer.create();


    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("Enhancement begins ~~~");
        Object result = methodProxy.invokeSuper(o, objects);
        System.out.println("Enhancement over ~~~");
        returnresult; }}Copy the code

The test test class

public class test {

    public static void main(String[] args) {
        UserServiceCGlib serviceCGlib = new UserServiceCGlib(newUserServiceImpl()); UserServiceImpl userService = (UserServiceImpl)serviceCGlib.getProxyInstance(); userService.addUser(); System.out.println(); userService.deleteUser(); }}Copy the code

Visibility is enhanced to print out logging



πŸ”₯ Application Scenario

Here I believe that you have basically mastered the difference and implementation of JDK dynamic proxy and CGlib dynamic proxy

However, in the interview process, πŸ”₯ in addition to the above points, you should also answer how they are used πŸ”₯, which is an interview bonus ✨

✨ What are the use scenarios for these two dynamic proxies??

Spring AOP

Here is how Spring AOP creates a proxy

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

   if(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<? > targetClass = config.getTargetClass();if (targetClass == null) {
         throw new AopConfigException("TargetSource cannot determine target class: " +
               "Either an interface or a target is required for proxy creation.");
      }
      / / if
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
         return new JdkDynamicAopProxy(config);
      }
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      return newJdkDynamicAopProxy(config); }}Copy the code

If the target object does not implement the interface, you must use the CGLIB library, and Spring will automatically convert between the JDK dynamic proxy and CGLIB

If you want to force CGLIB to implement AOP, you need to configure spring.aop.proxy-target-class=true or @enableAspectJAutoProxy (proxyTargetClass =true)



❀ finally

I am aCode pipi shrimp, a prawns lover who loves to share knowledge, will update useful blog posts in the future, looking forward to your attention!!

Creation is not easy, if this blog is helpful to you, I hope you can == one key three even oh! Thank you for your support. See you next time