Detailed introduction and simple example of Spring automatic agent creator

  • 2021-12-12 05:17:45
  • OfStack

Spring Automatic Agent Creator

Foreword:

In the classic spring Aop, the proxy Bean can be created manually for the target Bean, and the configuration file must declare one proxy for every Bean that needs enhancement, resulting in a large number of proxy Bean declared in the configuration file.

In the classic Spring Aop, Spring provides an automatic proxy creator (Aotu proxy creator), which eliminates the need to manually create proxies using ProxyFactoryBean.

Interfaces Animal and Book:


 package com.zzj.aop; public interface Animal { public void eat(); public void drink(); }

package com.zzj.aop; 
 
public interface Book { 
 public void read(); 
} 

Target class:


package com.zzj.aop; 
 
public class Human implements Animal, Book{ 
 @Override 
 public void eat() { 
  System.out.println("eat..."); 
 } 
 
 @Override 
 public void drink() { 
  System.out.println("drink..."); 
 } 
 
 @Override 
 public void read() { 
  System.out.println("read..."); 
 } 
} 

Pre-notification and post-notification:


package com.zzj.aop; 
 
import java.lang.reflect.Method; 
 
import org.springframework.aop.MethodBeforeAdvice; 
 
public class MethodBefore implements MethodBeforeAdvice { 
 
 public void before(Method arg0, Object[] arg1, Object arg2) 
   throws Throwable { 
  System.out.println("before " + arg0.getName()); 
 } 
 
} 


package com.zzj.aop; 
 
import java.lang.reflect.Method; 
 
import org.springframework.aop.AfterReturningAdvice; 
 
public class MethodAfter implements AfterReturningAdvice { 
 
 public void afterReturning(Object arg0, Method arg1, Object[] arg2, 
   Object arg3) throws Throwable { 
  System.out.println( "after " + arg1.getName()); 
 } 
 
} 

Spring configuration file:


<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans.xsd"> 
  <!--  Define the target object  --> 
  <bean id="human" class="com.zzj.aop.Human"></bean> 
  
  <!--  Defining Notifications  --> 
  <bean id="beforeAdvice" class="com.zzj.aop.MethodBefore"></bean> 
  <bean id="afterAdvice" class="com.zzj.aop.MethodAfter"></bean> 
  
  <!--  Define cut-in points  --> 
  <bean id="methodNamePointcut" 
   class="org.springframework.aop.support.NameMatchMethodPointcut"> 
   <property name="mappedNames"> 
    <list> 
     <value>eat</value> 
     <value>read</value> 
    </list> 
   </property> 
  </bean> 
  
  <!--  Define post enhancers (associated notifications and pointcuts)  --> 
  <bean id="AfterMethodNameAdvisor" 
   class="org.springframework.aop.support.DefaultPointcutAdvisor"> 
   <property name="advice" ref="afterAdvice"></property> 
   <property name="pointcut" ref="methodNamePointcut"></property> 
  </bean> 
  <!--  Define pre-enhancers (associated notifications and pointcuts)  --> 
  <bean id="BeforeMethodNameAdvisor" 
   class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor"> 
   <property name="advice" ref="beforeAdvice"></property> 
   <property name="expression"> 
    <value>execution(* *.*in*(..))</value><!--  Matchable drink --> 
   </property> 
  </bean> 
  
  <!--  Defining an automatic proxy creator  --> 
  <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> 
   <property name="beanNames"> 
    <list> 
     <value>*human</value> 
    </list> 
   </property> 
   <property name="interceptorNames"> 
    <list> 
     <value>AfterMethodNameAdvisor</value> 
     <value>BeforeMethodNameAdvisor</value> 
    </list> 
   </property> 
  </bean> 
</beans> 

The above auto-proxy can create a proxy for Bean ending in human.

Test:



package com.zzj.aop; 
 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 
 
public class Test { 
 
 /** 
  * @param args 
  */ 
 public static void main(String[] args) { 
  ApplicationContext context = new ClassPathXmlApplicationContext( 
    "applicationContext.xml"); 
  Animal animal = (Animal) context.getBean("human"); 
  Book book = (Book) animal; 
  animal.eat(); 
  animal.drink(); 
  book.read(); 
 
 } 
 
} 

Output:


eat... 
after eat 
before drink 
drink... 
read... 
after read 

Spring also provides another automatic proxy creator: DefaultAdvisorAutoProxyCreator. This automatic proxy creator does not require any configuration and automatically checks every enhancer and Bean declared in the Ioc container. If there is an Bean that matches the enhancer pointcut, DefaultAdvisorAutoProxyCreator will automatically create a proxy for it.


<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/> 

It should be noted that DefaultAdvisorAutoProxyCreator may proxy target Bean that you don't want to be proxy, so use it with great care.

Thank you for reading, hope to help everyone, thank you for your support to this site!


Related articles: