Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the problem of method invalidation in Spring AOP intercepting Abstract Class parent Class

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly introduces how to solve the problem of method invalidation in the parent class of Spring AOP intercepting abstract class. it is very detailed and has a certain reference value. Interested friends must read it!

Background

In the recent work, it is necessary to monitor and alarm the third-party interfaces that each system in the group depends on, and the interfaces with problems downstream can be sensed in time. First, we write a Spring AOP comment to collect the information returned when a third party is called. We call a third-party class to abstract a parent class. And add our custom comments to the parent method to monitor the log and print the log.

Many subclasses inherit this parent class and use methods in the parent class. Such as:

The problem occurs when calling the doSomething method of the subclass, and it is found that Spring AOP does not intercept the doPost () method. When adding annotations to subclass methods, Spring AOP can intercept subclass methods, but this is not the result we want. When we inject the parent class into the subclass through @ Autowired instead of using inheritance to call methods in the parent class, Spring AOP can intercept methods in the parent class. At this point, it is found that the problem lies in inheritance.

Cause analysis

The implementation principle of Spring AOP interceptor is to use dynamic proxy technology to realize aspect-oriented programming. There are two kinds of proxy implementation of Spring: one is based on JDK Dynamic Proxy technology, the other is based on CGLIB technology. If the target object implements the interface, by default Spring uses JDK's dynamic proxy to implement AOP. In this example, the target object does not implement the interface, so the CGLIB implementation dynamic proxy proxies the SuperClass object, and then enhances the doPost () method. The following code shows why Spring AOP does not enhance the doPost () method.

Figure 2 is equivalent to figure 3, even if the doPost () method is called with the super keyword, which shows that when we use the doPost () method called by the instance of SuperClass, when we use Spring AOP, the Bean objects we get from the IOC container are actually proxy objects, not those Bean objects themselves. Therefore, AOP cannot use proxy objects to call methods of these parent classes.

Solution

Knowing the cause of the problem, it is easier to solve the problem. Because the super keyword we use does not work to call the method of the parent class, then we force the use of the proxy object to call the parent method.

All right, we ran the program and found that there was no intercept method and an error was reported.

Java.lang.IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to' true' to make it available.

The exception message is very clear, can not find the current agent, we need to expose the agent, let's take a look at the source code of the AopContext class, see what went wrong, and see where we output the error message.

Package org.springframework.aop.framework;import org.springframework.core.NamedThreadLocal;import org.springframework.lang.Nullable;public final class AopContext {private static final ThreadLocal currentProxy = new NamedThreadLocal ("Current AOP proxy"); private AopContext () {} public static Object currentProxy () throws IllegalStateException {Object proxy = currentProxy.get (); if (proxy = = null) {throw new IllegalStateException ("Cannot find current proxy: Set 'exposeProxy' property on Advised to' true' to make it available.") } else {return proxy;}} @ Nullable static Object setCurrentProxy (@ Nullable Object proxy) {Object old = currentProxy.get (); if (proxy! = null) {currentProxy.set (proxy);} else {currentProxy.remove ();} return old;}}

It is said that the name setCurrentProxy method has not been called. Through searching, it is found that there are two classes that call the method, namely CglibAopProxy and JdkDynamicAopProxy. These two are the proxy methods of Spring aop. Because the target object we are discussing is not interface-based, the proxies used in this article are all based on CglibAopProxy. We find the place where the setCurrentProxy method is called in this class, and determine whether this.advised.exposeProxy is true in the program. If it is true, set the current proxy. By debugging this field is false

If (this.advised.exposeProxy) {oldProxy = AopContext.setCurrentProxy (proxy); setProxyContext = true;}

So let's add the following comments to the class where you need to notify, that is, the class where you need to intercept methods.

@ EnableAspectJAutoProxy (exposeProxy = true)

This time in the call, it is found that you can intercept the annotation method.

Postscript

There are many ways to solve this problem, but the subclass does not inherit the parent class, but changes to the @ Autowired mode, and then every place of call needs to add the object of the parent class.

Finally, our scheme in the program is to add a proxy class of the parent class, which is used to force the use of the proxy object to call the methods of the parent class. The subclass of the original parent class can inherit the proxy class.

Import org.springframework.aop.framework.AopContext;import org.springframework.stereotype.Component;import java.util.Map;@Componentpublic class ProxyAgent extends BaseAgent {private BaseAgent getProxyObject () {return ((BaseAgent) AopContext.currentProxy ());} protected String doGet (String url, Map headers, Map params, Object... UriVariables) {return getProxyObject (). DoGetBase (url, headers, params, uriVariables);} protected String doPost (String url, Map headers, Object body) {return getProxyObject (). DoPostBase (url, headers, body);} protected String doPostForm (String url, Map params) {return doPostForm (url, null, params);} protected String doPostForm (String url, Map headers, Map params) {return getProxyObject (). DoPostFormBase (url, headers, params) } protected String doPostFormWithContentHeader (String url, Map headers, Map params, byte [] boundary) {return getProxyObject (). DoPostFormWithContentHeaderBase (url, headers, params, boundary);} protected String doPostFormUpload (String url, Map headers, Map params) {return getProxyObject (). DoPostFormUploadBase (url, headers, params);}}

Similarly, the same problem occurs when calling internal methods to use the this keyword, just by enforcing the use of proxy objects.

These are all the contents of this article entitled "how to solve the problem of method invalidation in the parent class of an abstract class intercepted by Spring AOP". Thank you for reading! Hope to share the content to help you, more related knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report