“This is the 40th day of my participation in the First Challenge 2022. For details: First Challenge 2022”

1. What is agency

Many people must have heard and seen the air ticket agent, train ticket agent. What these agents do is sell train tickets for airlines and train stations. They’re kind of a middleman. The actual services are not provided by them. It’s provided by a real service provider. From this example, we can see what a proxy is: it has the functionality of the target object, while enhancing the service.

2. What are static and dynamic proxies?

The proxy pattern is the Java design pattern, which is characterized by proxy classes having the same interface as delegate classes. The proxy class is responsible for the delegate class preprocessing the message, filtering the message, passing the message to the delegate class, and post-processing the message. There is an association between the proxy class and the delegate class. An object of a proxy class is associated with an object of a delegate class, and the object of a proxy class is not itself an implementation of a real service. Instead, the corresponding service is provided by invoking methods of the delegate class. This fits perfectly with the real-life example above

There are two types of agents based on when they were created:

  • Static agent

    Source code is created by programmers or automatically generated by specific tools and then compiled. The.class file for the proxy class exists before the program runs. Static proxies typically represent only one class, while dynamic proxies represent multiple implementation classes under an interface. Static agents know in advance what they are proiding.

  • A dynamic proxy

    When the program is running, the reflection mechanism is used to create it dynamically. A dynamic proxy doesn’t know what to delegate except at run time

3. Static proxy

The code:

public interface TestService {

    void say(String msg);

}
Copy the code
public class TestServiceImpl implements TestService{
    @Override
    public void say(String msg) { System.out.println(msg); }}Copy the code
public class ProxyTestService implements TestService{

    private TestService testService;

    public ProxyTestService(TestService testService) {
        this.testService = testService;
    }

    @Override
    public void say(String msg) {

        / / pretreatment
        System.out.println("before calling say");
        // Invoke proxied testService
        testService.say(msg);
        // After the event
        System.out.println("after calling say"); }}Copy the code

Perform:

public class Test {

    public static void main(String[] args) throws Exception{
       TestService service = new TestServiceImpl();
       TestService service1 = new ProxyTestService(service);
       service1.say("ssssssss"); }}Copy the code

Static proxies are used to process data before and after the proxy class. The pre – and post-processing here is the enhancement of functionality

Dynamic proxy

In contrast to static proxy classes, dynamic proxy classes have their bytecodes dynamically generated by Java reflection at program runtime without the programmer having to manually write their source code. Dynamic proxy classes not only simplify programming but also improve the extensibility of software systems because Java reflection can generate any type of dynamic proxy class. The Proxy class and the InvocationHandler interface in the java.lang.Reflect package provide the ability to generate dynamic Proxy classes.

  • JDK native proxy

    The code:

    public interface TestService {
        void say(String msg);
    }
    
    public class TestServiceImpl implements TestService{
        @Override
        public void say(String msg) { System.out.println(msg); }}Copy the code
    public class TestInvocationHandler implements InvocationHandler {
    
        private Object target;
    
        public TestInvocationHandler(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println(proxy.getClass().getName());
            returnmethod.invoke(target,args); }}Copy the code
    public class Test {
    
        public static void main(String[] args) throws Exception{
            TestService testService =  (TestService)Proxy.newProxyInstance(Test.class.getClassLoader(), newClass<? >[]{TestService.class},new TestInvocationHandler(new TestServiceImpl()));
            testService.say("sssss"); }}Copy the code
  • Additional agent

public class EnhancerForSampleClassApplication {

    public static void main(String[] args) {

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(A.class);
        enhancer.setCallback(new MxsmPoxy());
        A a = (A)enhancer.create();
        a.aaa("bbb");
    }

   public interface A{

        public void aaa(String aaa);

   }

   public static  class MxsmPoxy implements MethodInterceptor{

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

           System.out.println( method.getName());
           System.out.println(args[0]);
			// What does the implementer decide here
           return null; }}}Copy the code

Cglib can also be used with reference to the Spring core package. It becomes clearer to look at Spring code’s use of Cglib.

Tips: Many RPC calls are based on dynamic proxy implementations, such as Dubbo.

5. To summarize

  • Enhancements in the proxy for static and dynamic proxy code is printing information, you can not only perform the function of the proxy but also perform other operations on it.
  • Dynamic proxies differ from static proxies in that the functionality is determined before compilation.
  • JDK native proxies can only be used for interfaces, both Cglib proxy interfaces and classes

I am ant back elephant, the article is helpful to you like to pay attention to me, the article has incorrect place please give correct comments ~ thank you