How do I get a cglib proxy from Spring?

I want to intercept the method of the following simple class:

public class MessageWriter {
    public void writeMessage() {
        System.out.print("method");
    }
}

Using the CGLIB method interceptor:

import java.lang.reflect.Method;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.print("Cglib ");
        Object res = method.invoke(obj, args); 
        System.out.print(" proxy!");
        return res;
    }
}

And I can get a cglib proxy using cglib Enchancer:

CglibInterceptor cglibInterceptor = new CglibInterceptor(target);
MessageWriter cgLibProxy = (MessageWriter) Enhancer.create(MessageWriter.class, cglibInterceptor);
System.out.println("\ncglib proxy: ");
cgLibProxy.writeMessage();

This code works. However, I can't figure out how to get a cglib proxy from org.springframework.aop.framework.ProxyFactory or from org.springframework.cglib.proxy.Enhancer.create(), i.e. a cglib proxy from Spring?

If I write the following code:

MessageWriter cgLibSpringProxy = (MessageWriter) org.springframework.cglib.proxy.Enhancer.create(MessageWriter.class, cglibInterceptor);

Eclipse highlights create red:

enter a description of the image here

UPD

To more accurately reformulate my question, I am interested in is there any way to specify in the code that it is necessary to use a CGlib proxy, if the target class implements the interface? After all, " by default, when a target object equipped with a board implements some interface, Spring will use a dynamic JDK proxy to create proxy instances of the target object." Sort of like in in the configuration file, you can specify

<aop:config proxy-target-class="true">
    <!-- other beans defined here... -->
</aop:config>

But is there any way to do this in the code? And it seems like the ProxyFactory class has a {[10] method]}:

ProxyFactory pf = new ProxyFactory () ;
pf.setProxyTargetClass(true);

But according to the description in the documentation, I still did not understand whether setting this method in true EXACTLY obliges Spring to use CGLIB to create a proxy? Like, no? From the documentation about ProxyConfig. setProxyTargetClass():)

Set this to "true" to force proxying for the TargetSource's exposed target class. If that target class is an interface, a JDK proxy will be created for the given interface. If that target class is any other class, a CGLIB proxy will be created for the given class.

Author: Ksenia, 2018-03-13

3 answers

As far as I know, CGlib is used by default when creating a proxy without interfaces in Spring:

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;

public class SpringAop {

    public static class Entity {
        public void soSomething() {
            System.out.println("doing something");
        }
    }

    public static class Handler implements MethodInterceptor {

        @Override
        public Object invoke(MethodInvocation methodInvocation) throws Throwable {
            System.out.println("before calling method");
            Object returnedValue = methodInvocation.proceed();
            System.out.println("after calling method");
            return returnedValue;
        }
    }


    public static void main(String[] args) {
        Entity entity = new Entity();

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(entity);
        proxyFactory.addAdvice(new Handler());

        Entity entityProxy = (Entity) proxyFactory.getProxy();
        entityProxy.soSomething();
    }
}

Addition:

The fact is that if the target (target) has no interfaces, then the proxy will be created through inheritance from the target. To do this, cglib will be used. Otherwise, AspectJ is applied.

 1
Author: faoxis, 2018-03-13 11:01:07

The @Scope annotation allows you to specify how to create a proxy. You can force the use of CGLIB, even if the class has an interface. Like this:

@Service
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyService impements SomeInterface { ... }
 1
Author: Demel, 2019-04-10 05:15:44

I have this code working:

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;

    // ...

        Model model = new Model(1, "test");
        MethodInterceptor callback = (object, method, args, methodProxy) -> methodProxy.invoke(model, args);
        Model proxy = (Model) Enhancer.create(Model.class, callback);
        assertThat(proxy).isEqualTo(model);
 0
Author: Cepr0, 2020-04-19 16:52:12