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

The method of creating Agent by AOP in Spring

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

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

This article mainly explains "the method of creating agent in AOP in Spring". The content of the explanation in this article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "the method of creating agent in AOP in Spring".

1. Prepare to create proxy protected Object wrapIfNecessary (Object bean, String beanName, Object cacheKey) {/ / 1. Look for enhancer Object [] specificInterceptors = getAdvicesAndAdvisorsForBean (bean.getClass (), beanName, null); if (specificInterceptors! = DO_NOT_PROXY) {/ / 2. Create proxy Object proxy = createProxy (bean.getClass (), beanName, specificInterceptors, new SingletonTargetSource (bean)); return proxy;}} protected Object [] getAdvicesAndAdvisorsForBean (Class beanClass, String beanName, TargetSource targetSource) {/ / sixth AOP search Enhancer has analyzed this step List advisors = findEligibleAdvisors (beanClass, beanName); if (advisors.isEmpty ()) {return DO_NOT_PROXY;} return advisors.toArray () } protected Object createProxy (Class beanClass, String beanName, Object [] specificInterceptors, TargetSource targetSource) {/ / the creation and processing of the proxy class is left to ProxyFactory to handle. In this function, just do some preparatory work ProxyFactory proxyFactory = new ProxyFactory () / / get related attributes in the current class proxyFactory.copyFrom (this); if (! shouldProxyTargetClass (beanClass, beanName)) {/ / like interface com.lwh.spring.JdkProxy.PersonService Class [] targetInterfaces = ClassUtils.getAllInterfacesForClass (beanClass, this.proxyClassLoader); for (Class targetInterface: targetInterfaces) {/ / add proxy interface proxyFactory.addInterface (targetInterface) }} / / encapsulate the interceptor as an enhancer, where the interceptor type is Advisor [] advisors = buildAdvisors (beanName, specificInterceptors); for (Advisor advisor: advisors) {/ / and add proxyFactory.addAdvisor (advisor) to ProxyFactory;} / / SingletonTargetSource for target object [com.lwh.spring.JdkProxy.PersonServiceImpl@1130520d] proxyFactory.setTargetSource (targetSource) / / Custom proxy, empty implementation, subclass implementation customizeProxyFactory (proxyFactory); proxyFactory.setFrozen (this.freezeProxy); if (advisorsPreFiltered ()) {proxyFactory.setPreFiltered (true);} / / create proxy return proxyFactory.getProxy (this.proxyClassLoader);} protected Advisor [] buildAdvisors (String beanName, Object [] specificInterceptors) {Advisor [] commonInterceptors = resolveInterceptorNames (); List allInterceptors = new ArrayList () If (specificInterceptors! = null) {/ / add interceptor allInterceptors.addAll (Arrays.asList (specificInterceptors)); if (commonInterceptors! = null) {if (this.applyCommonInterceptorsFirst) {allInterceptors.addAll (0, Arrays.asList (commonInterceptors));} else {allInterceptors.addAll (Arrays.asList (commonInterceptors)) } Advisor [] advisors = new Advisor [allInterceptors.size ()]; for (int I = 0; I < allInterceptors.size ()) {/ / convert the interceptor to Advisor advisors [I] = this.advisorAdapterRegistry.wrap (allInterceptors.get (I));} return advisors;} public Advisor wrap (Object adviceObject) throws UnknownAdviceTypeException {if (adviceObject instanceof Advisor) {return (Advisor) adviceObject } if (! (adviceObject instanceof Advice)) {throw new UnknownAdviceTypeException (adviceObject);} Advice advice = (Advice) adviceObject; if (advice instanceof MethodInterceptor) {return new DefaultPointcutAdvisor (advice);} for (AdvisorAdapter adapter: this.adapters) {if (adapter.supportsAdvice (advice)) {return new DefaultPointcutAdvisor (advice);}} throw new UnknownAdviceTypeException (advice);} 2. Create proxy return proxyFactory.getProxy (this.proxyClassLoader) Public Object getProxy (ClassLoader classLoader) {return createAopProxy () .getProxy (classLoader);} protected final synchronized AopProxy createAopProxy () {if (! this.active) {activate ();} return getAopProxyFactory () .createAopProxy (this) } / / this function really completes the creation of the agent public AopProxy createAopProxy (AdvisedSupport config) throws AopConfigException {/ / three conditions affect the judgment / / 1.optimize attribute of Spring. Users are not recommended to use this setting / / 2.proxytargetclass attribute, which has been analyzed before. Whether the proxy interface 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 (targetClass.isInterface ()) {/ / use JDK dynamic proxy return new JdkDynamicAopProxy (config);} return CglibProxyFactory.createCglibProxy (config);} else {/ / target object implements the interface, default uses JDK dynamic proxy return new JdkDynamicAopProxy (config);}} 3, get proxy

Public Object getProxy (ClassLoader classLoader) {/ / first create the proxy, then get the proxy return createAopProxy (). GetProxy (classLoader);} public Object getProxy (ClassLoader classLoader) {/ / get the proxy interface, which is actually the dynamic proxy implementation of JDK. It is recommended to review JDK's dynamic proxy Class [] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces (this.advised); findDefinedEqualsAndHashCodeMethods (proxiedInterfaces); / / return proxy object return Proxy.newProxyInstance (classLoader, proxiedInterfaces, this) The key of JDK dynamic agent is to implement InvocationHandler method and its invoke method, and the JdkDynamicAopProxy here implements the InvocationHandler interface, so there must be an invoke method. Looking at the notes, we can see that the proxy object is PersonService personService = ctx.getBean ("personService", PersonService.class). What is actually called here is the sayHello method in the generated proxy class. See the following figure. Because it is a note made before, the package name is inconsistent, but the meaning is obvious. In the proxy class, the sayHello method will call the invoke method in InvocationHandler, and this h object, that is, InvocationHandler, is set when Proxy.newProxyInstance, so the following call to the sayHello method will first enter the invoke method personService.sayHello () of JdkDynamicAopProxy.

4. Analyze method call / / get proxy object PersonService personService = ctx.getBean ("personService", PersonService.class); / / method call personService.sayHello ()

Public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {MethodInvocation invocation; Object oldProxy = null; boolean setProxyContext = false; / / SingletonTargetSource for target object [com.lwh.spring.JdkProxy.PersonServiceImpl@6986852] TargetSource targetSource = this.advised.targetSource; Class targetClass = null; Object target = null; try {/ / deleted part of the code Object retVal; / / SingletonTargetSource for target object [com.lwh.spring.JdkProxy.PersonServiceImpl@6986852] target = targetSource.getTarget () If (target! = null) {/ / class com.lwh.spring.JdkProxy.PersonServiceImpl targetClass = target.getClass ();} / get the interceptor chain of the current method List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice (method, targetClass); if (chain.isEmpty ()) {/ / if the chain is empty, call the tangent method retVal = AopUtils.invokeJoinpointUsingReflection (target, method, args) directly } else {/ / encapsulates the interceptor in ReflectiveMethodInvocation to facilitate link calls using its proceed method invocation = new ReflectiveMethodInvocation (proxy, target, method, args, targetClass, chain); / / execute interceptor chain call retVal = invocation.proceed ();} Class returnType = method.getReturnType () If (retVal! = null & & retVal = = target & & returnType.isInstance (proxy) & &! RawTargetAccess.class.isAssignableFrom (method.getDeclaringClass () {retVal = proxy;} else if (retVal = = null & & returnType! = Void.TYPE & & returnType.isPrimitive ()) {} return retVal;} finally {}

Public Object proceed () throws Throwable {/ / We start with an index of-1 and increment early. / / execute the pointcut method after all the enhancement methods are executed, maintain a currentInterceptorIndex counter, increment if (this.currentInterceptorIndex = = this.interceptorsAndDynamicMethodMatchers.size ()-1) {return invokeJoinpoint ();} / / List interceptorsAndDynamicMethodMatchers, record the enhancement method to be executed, and obtain the enhancement method Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get (+ + this.currentInterceptorIndex) to be executed by subscript If (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {/ / Evaluate dynamic method matcher here: static part will already have / / been evaluated and found to match. InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; if (dm.methodMatcher.matches (this.method, this.targetClass, this.arguments)) {return dm.interceptor.invoke (this);} else {/ / Dynamic matching failed. / / Skip this interceptor and invoke the next in the chain. Return proceed ();}} else {/ / It's an interceptor, so we just invoke it: The pointcut will have / / been evaluated statically before this object was constructed. Return ((MethodInterceptor) interceptorOrInterceptionAdvice) .invoke (this);}} Thank you for your reading. The above is the content of "the method of creating agents in Spring". After the study of this article, I believe you have a deeper understanding of the method of creating agents in Spring, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

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

Internet Technology

Wechat

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

12
Report