`

Spring AOP 动态代理

 
阅读更多

AOP:面向切面、面向方面、面向接口是一种横切技术
横切技术运用:
1.事务管理: (1)数据库事务:(2)编程事务(3)声明事物:Spring AOP-->声明事物   
2.日志处理:
3.安全验证: Spring AOP---OOP升级  
  

静态代理原理:目标对象:调用业务逻辑    代理对象:日志管理
表示层调用--->代理对象(日志管理)-->调用目标对象

动态代理原理:spring AOP采用动态代理来实现
(1)实现InvocationHandler接口

(2)创建代理类(通过java API)

Proxy.newProxyInstance(动态加载代理类,代理类实现接口,使用handler);

(3)调用invoke方法(虚拟机自动调用方法)

日志处理
 //调用目标对象
 method.invoke("目标对象","参数");
 日志处理

通过代理对象--(请求信息)-->目标对象---(返回信息)----> 代理对象

 

Spring 动态代理中的基本概念

1、关注点(concern)
   一个关注点可以是一个特定的问题,概念、或者应用程序的兴趣点。总而言之,应用程序必须达到一个目标
   安全验证、日志记录、事务管理都是一个关注点
   在oo应用程序中,关注点可能已经被代码模块化了还可能散落在整个对象模型中
2、横切关注点(crosscutting concern)
   如何一个关注点的实现代码散落在多个类中或方法中
3、方面(aspect)
   一个方面是对一个横切关注点模块化,它将那些原本散落在各处的,
   用于实现这个关注点的代码规整在一处
4、建议(advice)通知
   advice是point cut执行代码,是方面执行的具体实现
5、切入点(pointcut)
   用于指定某个建议用到何处
6、织入(weaving)
   将aspect(方面)运用到目标对象的过程
7、连接点(join point)
  程序执行过程中的一个点 

通知类型:
  try{
    //前置通知
         //环绕通知
            //调用目标对象方法
         //环绕通知
    //后置通知
  }catch(){
    //异常通知
  }finally{
    //终止通知
  }

 

流程图

 

一.静态代理原理实例:

项目结构图:                                                                    

IUserServ接口代码

  1. public interface IUserServ {  
  2.     List<User> findAllUser();  
  3.     int deleteUserById(User user);  
  4.     int saveUser(User user);  
  5. }  
public interface IUserServ {
	List<User> findAllUser();
	int deleteUserById(User user);
	int saveUser(User user);
}


UserServImpl实现类代码

  1. public class UserServImpl implements IUserServ {  
  2.     public int deleteUserById(User user) {  
  3.         System.out.println("******执行删除方法******");  
  4.         return 0;  
  5.     }  
  6.     public List<User> findAllUser() {  
  7.         System.out.println("*******执行查询方法*******");  
  8.         return null;  
  9.     }  
  10.     public int saveUser(User user) {  
  11.         System.out.println("*******执行添加方法********");  
  12.         return 0;  
  13.     }  
  14. }  
public class UserServImpl implements IUserServ {
	public int deleteUserById(User user) {
		System.out.println("******执行删除方法******");
		return 0;
	}
	public List<User> findAllUser() {
		System.out.println("*******执行查询方法*******");
		return null;
	}
	public int saveUser(User user) {
		System.out.println("*******执行添加方法********");
		return 0;
	}
}

UserServProxyImpl实现类代码

  1. //代理类:完成日志输出   
  2. public class UserServProxyImpl implements IUserServ {  
  3.     // 访问目标对象(UserServImpl)   
  4.     // 代理对象(UserServProxyImpl)   
  5.     // 创建目标对象   
  6.     private IUserServ iuserServ ;//= new UserServImpl();   
  7.   
  8.     public UserServProxyImpl(IUserServ iuserServ){  
  9.         this.iuserServ = iuserServ;  
  10.     }  
  11.     public int deleteUserById(User user) {  
  12.         beforeLog();  
  13.         //调用目标对象里方法   
  14.         iuserServ.deleteUserById(user);  
  15.         afterLog();  
  16.         return 0;  
  17.     }  
  18.   
  19.     public List<User> findAllUser() {  
  20.         beforeLog();  
  21.         //调用目标对象里方法   
  22.         iuserServ.findAllUser();  
  23.         afterLog();  
  24.         return null;  
  25.     }  
  26.   
  27.     public int saveUser(User user) {  
  28.         beforeLog();  
  29.         //调用目标对象里方法   
  30.         iuserServ.saveUser(user);  
  31.         afterLog();  
  32.         return 0;  
  33.     }  
  34.   
  35.     private void beforeLog() {  
  36.         System.out.println("开始执行");  
  37.     }  
  38.       
  39.     private void afterLog() {  
  40.         System.out.println("执行完毕");  
  41.     }  
  42. }  
//代理类:完成日志输出
public class UserServProxyImpl implements IUserServ {
	// 访问目标对象(UserServImpl)
	// 代理对象(UserServProxyImpl)
	// 创建目标对象
	private IUserServ iuserServ ;//= new UserServImpl();

	public UserServProxyImpl(IUserServ iuserServ){
		this.iuserServ = iuserServ;
	}
	public int deleteUserById(User user) {
		beforeLog();
        //调用目标对象里方法
		iuserServ.deleteUserById(user);
		afterLog();
		return 0;
	}

	public List<User> findAllUser() {
		beforeLog();
		//调用目标对象里方法
		iuserServ.findAllUser();
		afterLog();
		return null;
	}

	public int saveUser(User user) {
		beforeLog();
		//调用目标对象里方法
		iuserServ.saveUser(user);
		afterLog();
		return 0;
	}

	private void beforeLog() {
		System.out.println("开始执行");
	}
	
	private void afterLog() {
		System.out.println("执行完毕");
	}
}

ActionTest测试类代码

  1. public class ActionTest {  
  2.     public static void main(String[] args) {  
  3.         //用户访问代理对象---信息->目标对象   
  4.         IUserServ iuserServ = new UserServProxyImpl(new UserServImpl());  
  5.         iuserServ.findAllUser();  
  6.     }  
  7. }  
public class ActionTest {
	public static void main(String[] args) {
		//用户访问代理对象---信息->目标对象
		IUserServ iuserServ = new UserServProxyImpl(new UserServImpl());
		iuserServ.findAllUser();
	}
}

运行结果:

开始执行
*******执行查询方法*******
执行完毕
二.动态代理实例

项目结构图:

IUserServ接口代码与UserServImpl实现类代码和上述代码相同

LogHandler类代码

  1. public class LogHandler implements InvocationHandler {  
  2.     //目标对象   
  3.     private Object targetObject;  
  4.     /** 
  5.      * 创建动态代理类 
  6.      * @return object(代理类) 
  7.      */  
  8.     public Object createProxy(Object targetObject){  
  9.         this.targetObject = targetObject;  
  10.         return Proxy.newProxyInstance(  
  11.                 targetObject.getClass().getClassLoader(),   
  12.                     targetObject.getClass().getInterfaces(), this);  
  13.     }  
  14.     @Override  
  15.     public Object invoke(Object proxy, Method method, Object[] args)  
  16.             throws Throwable {  
  17.         Object obj = null;  
  18.         try {  
  19.             beforeLog();  
  20.             //obj: 目标对象--->代理对象的返回值--->返回给调用者的信息   
  21.             //this.invoke("目标对象","代理对象给目标对象传递参数");   
  22.             //调用目标对象中方法   
  23.             obj = method.invoke(targetObject, args);  
  24.             afterLog();  
  25.         } catch (Exception e) {  
  26.             e.printStackTrace();  
  27.         }  
  28.         return obj;  
  29.     }  
  30.       
  31.     //日志管理方法   
  32.     private void beforeLog(){  
  33.         System.out.println("开始执行");  
  34.     }  
  35.       
  36.     private void afterLog(){  
  37.         System.out.println("执行完毕");  
  38.     }  
  39.   
  40. }  
public class LogHandler implements InvocationHandler {
	//目标对象
	private Object targetObject;
	/**
	 * 创建动态代理类
	 * @return object(代理类)
	 */
	public Object createProxy(Object targetObject){
		this.targetObject = targetObject;
		return Proxy.newProxyInstance(
				targetObject.getClass().getClassLoader(), 
					targetObject.getClass().getInterfaces(), this);
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object obj = null;
		try {
			beforeLog();
			//obj: 目标对象--->代理对象的返回值--->返回给调用者的信息
			//this.invoke("目标对象","代理对象给目标对象传递参数");
			//调用目标对象中方法
			obj = method.invoke(targetObject, args);
			afterLog();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}
	
	//日志管理方法
	private void beforeLog(){
		System.out.println("开始执行");
	}
	
	private void afterLog(){
		System.out.println("执行完毕");
	}

}

ActionTest测试类代码:

  1. public class ActionTest {  
  2.     public static void main(String[] args) {  
  3.         //创建代理对象iuserServ   
  4.         LogHandler handler = new LogHandler();  
  5.         IUserServ iuserServ = (IUserServ)handler.createProxy(new UserServImpl());  
  6.         iuserServ.deleteUserById(new User());  
  7.     }  
  8. }  
public class ActionTest {
	public static void main(String[] args) {
		//创建代理对象iuserServ
		LogHandler handler = new LogHandler();
		IUserServ iuserServ = (IUserServ)handler.createProxy(new UserServImpl());
		iuserServ.deleteUserById(new User());
	}
}

运行结果:
开始执行
******执行删除方法******
执行完毕
三.Spring AOP使用(2.x版本之前)

项目结构图:



IUserServ接口代码与UserServImpl实现类代码和上述代码相同

配置步骤:

1、配置目标对象(applicationContext.xml)

  1. <bean id="userServTarget" class="com.tarena.biz.impl.UserServImpl"/>   
<bean id="userServTarget" class="com.tarena.biz.impl.UserServImpl"/> 

 2、配置通知
(a)前置通知(BeforeLogAdvice)

  1. public class BeforeLogAdvice implements MethodBeforeAdvice {  
  2.      /** 
  3.         * Method method:调用目标对象的方法 
  4.         * Object[] args:发送给目标对象的参数列表 
  5.         * Object target:目标对象 
  6.         */  
  7.     public void before(Method method, Object[] args, Object target)  
  8.             throws Throwable {  
  9.         beforeLog();  
  10.     }  
  11.     private void beforeLog(){  
  12.         System.out.println("开始执行");  
  13.     }  
  14. }  
public class BeforeLogAdvice implements MethodBeforeAdvice {
	 /**
	    * Method method:调用目标对象的方法
	    * Object[] args:发送给目标对象的参数列表
	    * Object target:目标对象
	    */
	public void before(Method method, Object[] args, Object target)
			throws Throwable {
		beforeLog();
	}
	private void beforeLog(){
		System.out.println("开始执行");
	}
}


(b)后置通知(AfterLogAdvice)

  1. public class AfterLogAdvice implements AfterReturningAdvice {  
  2.       /** 
  3.         * Object returnValue:目标对象返回值 
  4.         *  Method method:目标对象方法名 
  5.         *  Object[] args:目标对象参数列表 
  6.         *  Object target:目标对象 
  7.         */  
  8.     public void afterReturning(Object returnValue, Method method,  
  9.             Object[] args, Object target) throws Throwable {  
  10.         afterLog();  
  11.     }  
  12.     private void afterLog(){  
  13.         System.out.println("执行完毕");  
  14.     }  
  15. }  
public class AfterLogAdvice implements AfterReturningAdvice {
	  /**
	    * Object returnValue:目标对象返回值
	    *  Method method:目标对象方法名
	    *  Object[] args:目标对象参数列表
	    *  Object target:目标对象
	    */
	public void afterReturning(Object returnValue, Method method,
			Object[] args, Object target) throws Throwable {
		afterLog();
	}
	private void afterLog(){
		System.out.println("执行完毕");
	}
}

       

(c)在spring容器中,让容器管理通知(applicationContext.xml)

  1. <!-- 定义通知 -->  
  2.         <!-- 前置通知 -->  
  3.         <bean id="beforeLogAdvice" class="com.tarena.advice.BeforeLogAdvice"/>  
  4.         <!-- 后置通知 -->  
  5.         <bean id="afterLogAdvice" class="com.tarena.advice.AfterLogAdvice"/>  
<!-- 定义通知 -->
		<!-- 前置通知 -->
		<bean id="beforeLogAdvice" class="com.tarena.advice.BeforeLogAdvice"/>
		<!-- 后置通知 -->
		<bean id="afterLogAdvice" class="com.tarena.advice.AfterLogAdvice"/>


3、配置代理对象(applicationContext.xml)  

  1. <!-- 代理类作用: 生成代理类,织入通知 -->    
  2.   <bean id="userServProxy"   
  3.    class="org.springframework.aop.framework.ProxyFactoryBean">  
  4.    <property name="interfaces">  
  5.    <!-- 可以添加多个接口 -->  
  6.     <list>  
  7.      <value>com.tarena.biz.IUserServ</value>  
  8.     </list>  
  9.    </property>  
  10.    <!-- 引入通知 -->  
  11.    <property name="interceptorNames">  
  12.     <list>  
  13.      <value>beforeLogAdvice</value>  
  14.      <value>afterLogAdvice</value>  
  15.     </list>  
  16.    </property>  
  17.    <!-- 目标对象 -->  
  18.    <property name="target" ref="userServTarget"/>  
  19.   </bean>  
<!-- 代理类作用: 生成代理类,织入通知 -->  
  <bean id="userServProxy" 
   class="org.springframework.aop.framework.ProxyFactoryBean">
   <property name="interfaces">
   <!-- 可以添加多个接口 -->
    <list>
     <value>com.tarena.biz.IUserServ</value>
    </list>
   </property>
   <!-- 引入通知 -->
   <property name="interceptorNames">
    <list>
     <value>beforeLogAdvice</value>
     <value>afterLogAdvice</value>
    </list>
   </property>
   <!-- 目标对象 -->
   <property name="target" ref="userServTarget"/>
  </bean>


 4.访问()
Spring容器:通过代理对象调用-->织入通知--->目标对象
程序员:访问代理对象   

测试类(ActionTest):

  1. public class ActionTest {  
  2.     public static void main(String[] args) {  
  3.         ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");  
  4.         IUserServ iuserServ = (IUserServ)ac.getBean("userServProxy");  
  5.         iuserServ.deleteUserById(new User());  
  6.         iuserServ.findAllUser();  
  7.     }  
  8. }  
public class ActionTest {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		IUserServ iuserServ = (IUserServ)ac.getBean("userServProxy");
		iuserServ.deleteUserById(new User());
		iuserServ.findAllUser();
	}
}

运行结果:

开始执行
******执行删除方法******
执行完毕
开始执行
*******执行查询方法*******
执行完毕
四.Spring AOP使用(2.x版本之后)这种方式需要额外添加两个jar包,

存放位置在spring-framework-2.5.6.SEC01\lib\aspectj文件夹下。

项目结构图


IUserServ接口代码与UserServImpl实现类代码和上述代码相同

LogAdvice中

  1. public class LogAdvice {  
  2.     public void beforeLog(){  
  3.         System.out.println("开始执行");  
  4.     }  
  5.     public void afterLog(){  
  6.         System.out.println("执行完毕");  
  7.     }  
  8. }  
public class LogAdvice {
	public void beforeLog(){
		System.out.println("开始执行");
	}
	public void afterLog(){
		System.out.println("执行完毕");
	}
}

applicationContext.xml中

  1. <!-- spring2.x后 -->  
  2.     <!-- 目标对象 -->  
  3.     <bean id="userServImpl" class="com.tarena.biz.impl.UserServImpl"/>  
  4.     <!-- 通知 -->  
  5.     <bean id="logAdvice" class="com.tarena.advice.LogAdvice"/>  
  6.       
  7.     <aop:config>  
  8.         <aop:aspect id="logAspect" ref="logAdvice">  
  9.             <!-- 切入点 -->  
  10.             <aop:pointcut id="beforePointCut"   
  11.         expression="execution(* saveUser*(..))"/>  
  12.         <aop:pointcut id="afterPointCut"   
  13.         expression="execution(* saveUser*(..))"/>  
  14.               
  15.             <!-- 织入(通知作用于切入点) -->  
  16.             <aop:before method="beforeLog" pointcut-ref="beforePointCut"/>  
  17.             <aop:after method="afterLog" pointcut-ref="afterPointCut"/>  
  18.         </aop:aspect>  
  19.     </aop:config>  
<!-- spring2.x后 -->
	<!-- 目标对象 -->
	<bean id="userServImpl" class="com.tarena.biz.impl.UserServImpl"/>
	<!-- 通知 -->
	<bean id="logAdvice" class="com.tarena.advice.LogAdvice"/>
	
	<aop:config>
		<aop:aspect id="logAspect" ref="logAdvice">
			<!-- 切入点 -->
			<aop:pointcut id="beforePointCut" 
	    expression="execution(* saveUser*(..))"/>
	    <aop:pointcut id="afterPointCut" 
	    expression="execution(* saveUser*(..))"/>
			
			<!-- 织入(通知作用于切入点) -->
			<aop:before method="beforeLog" pointcut-ref="beforePointCut"/>
			<aop:after method="afterLog" pointcut-ref="afterPointCut"/>
		</aop:aspect>
	</aop:config>

测试类:

  1. public class ActionTest {  
  2.     public static void main(String[] args) {  
  3.         ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");  
  4.         IUserServ iuserServ = (IUserServ)ac.getBean("userServImpl");  
  5.         iuserServ.deleteUserById(new User());  
  6.         iuserServ.findAllUser();  
  7.         iuserServ.saveUser(new User());  
  8.     }  
  9. }  
public class ActionTest {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		IUserServ iuserServ = (IUserServ)ac.getBean("userServImpl");
		iuserServ.deleteUserById(new User());
		iuserServ.findAllUser();
		iuserServ.saveUser(new User());
	}
}

运行结果
******执行删除方法******
*******执行查询方法*******
开始执行
*******执行添加方法********
执行完毕

注:如果要在业务层所有的方法前后添加日志文件,则需要更改为以下配置

  1. <aop:pointcut id="beforePointCut"   
  2.         expression="execution(* com.tarena.biz.*.*(..))"/>  
  3.         <aop:pointcut id="afterPointCut"   
  4.         expression="execution(* com.tarena.biz.*.*(..))"/>  
<aop:pointcut id="beforePointCut" 
	    expression="execution(* com.tarena.biz.*.*(..))"/>
	    <aop:pointcut id="afterPointCut" 
	    expression="execution(* com.tarena.biz.*.*(..))"/>


运行结果:

开始执行
******执行删除方法******
执行完毕
开始执行
*******执行查询方法*******
执行完毕
开始执行
*******执行添加方法********
执行完毕

分享到:
评论

相关推荐

    Spring框架+SpringAOP动态代理

    ### Spring框架+SpringAOP动态代理 #### 一、Spring AOP 动态代理概述 在探讨Spring AOP(Aspect-Oriented Programming,面向切面编程)中的动态代理之前,我们首先简要回顾一下AOP的基本概念。面向切面编程是一种...

    反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

    Spring AOP支持不同的代理策略,包括JDK动态代理和CGLIB代理。如果被代理的类没有实现接口,Spring AOP会采用CGLIB来生成代理对象。CGLIB(Code Generation Library)是一个开源的代码生成库,它允许运行时在内存中...

    spring之AOP(动态代理)

    在Spring中,AOP主要通过两种动态代理技术实现:JDK动态代理和CGLIB动态代理。 首先,让我们详细了解一下JDK动态代理。JDK动态代理基于Java的接口实现,它适用于目标对象实现了至少一个接口的情况。在运行时,JDK...

    Java动态代理(Spring Aop原理)

    在Spring框架中,AOP(面向切面编程)就是基于Java动态代理来完成的,用于实现横切关注点,如日志、事务管理等。这篇博客的文章链接虽然没有给出具体内容,但我们可以根据Java动态代理和Spring AOP的基本概念来深入...

    Spring AOP 动态代理(二)

    Spring AOP 的本质其实就是实现了动态代理,这个和Aspectj不一样,AspectJ 是直接修改你的字节码 完成的 代理模式其实很简单 主要包括 接口+真实的实现类+代理类 在真实类的实例化的时候 使用代理类,所以需要 ...

    springAOP配置动态代理实现

    动态代理则是Spring AOP实现的核心技术之一,它允许我们在运行时创建具有额外行为的对象。下面将详细阐述Spring AOP的配置以及动态代理的实现。 一、Spring AOP基础知识 1. **什么是AOP**:AOP是一种编程范式,...

    springAop默认代理方式.zip

    Spring AOP会为每个目标对象创建一个子类,并覆盖其方法,添加AOP代理逻辑。 4. **代理模式的创建**:Spring AOP 使用`org.springframework.aop.framework.ProxyFactoryBean`或`@EnableAspectJAutoProxy`注解来配置...

    死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序.pdf

    在 Spring 中,AOP 的实现主要依赖于代理模式,有两种代理方式:JDK 动态代理和 CGLIB 动态代理。 JDK 动态代理是基于接口的,它要求被代理的目标对象必须实现至少一个接口。Spring 使用 `java.lang.reflect.Proxy`...

    反射实现 AOP 动态代理模式(Spring AOP 的实现 原理) - Java 例子 -

    Spring框架是Java中实现AOP的一个流行工具,它通过动态代理机制实现了这一功能。本文将深入探讨Spring AOP的实现原理,以及如何使用反射来实现动态代理模式。 首先,我们需要了解AOP的基本概念。AOP的核心思想是切...

    spring aop jar 包

    `aop-jar`这个压缩包可能包含了Spring AOP的实现类、接口、以及其他相关的辅助类,例如动态代理类、切点匹配器等。在项目中,我们通常会将这个jar包引入到类路径下,以便使用Spring AOP的功能。 总的来说,Spring ...

    JDK动态代理 spring aop 的原理

    5. AOP代理的使用:当通过Spring的依赖注入(DI)获取到一个对象时,实际上得到的是一个代理对象。通过这个代理对象调用方法,Spring会自动插入预先定义好的通知逻辑。 总的来说,JDK动态代理是Spring AOP实现的...

    Spring-AOP-JDK动态代理

    本篇将详细讲解Spring中的AOP实现,特别是JDK动态代理的应用。 首先,我们要了解什么是AOP(Aspect Oriented Programming,面向切面编程)。AOP是一种编程范式,旨在解决应用程序中分散的、横切关注点的问题,如...

    Spring AOP 16道面试题及答案.docx

    Spring AOP代理是框架为实现切面功能创建的对象,它在运行时实现切面协议。Spring提供了两种代理方式:JDK动态代理和CGLIB代理。JDK代理适用于那些实现了接口的类,而CGLIB代理则适用于没有实现接口的类。 引介...

    SpringAOP之探秘(动态代理、责任链模式、注解使用)

    本篇文章将深入探讨Spring AOP中的动态代理、责任链模式以及注解的使用。 首先,动态代理是实现AOP的关键技术之一。在Java中,有两种主要的动态代理实现方式:JDK动态代理和CGLIB。JDK动态代理基于接口,当目标类...

    AOP动态代理(反射机制)

    4. **应用场景**:AOP动态代理常用于框架开发,例如Spring AOP。Spring AOP提供了基于代理的实现,可以在不修改原始代码的情况下,为业务方法添加额外的功能。此外,它还支持基于注解的切面定义,使得AOP的使用更加...

    简单spring aop 例子

    1. **代理**:Spring AOP支持两种类型的代理:JDK动态代理和CGLIB代理。JDK代理用于实现了接口的类,而CGLIB代理则用于没有接口或不希望使用接口的类。代理对象在调用目标方法时会执行切面逻辑。 2. **织入**:织入...

    spring动态代理原理

    - 在Spring AOP中,有两种动态代理方式:JDK动态代理和CGLIB代理。JDK代理适用于目标对象实现了一个或多个接口的情况,而CGLIB代理则在目标对象没有接口或者接口数量多且复杂时使用。 - Spring会根据目标对象是否...

    通过动态代理模拟Spring AOP

    本篇文章将详细探讨如何通过Java的动态代理机制来模拟Spring AOP的核心概念。 首先,让我们了解什么是动态代理。在Java中,动态代理主要由`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口...

    Spring AOP实现机制

    Spring AOP主要通过两种方式实现:JDK动态代理和CGLIB代理。 - **JDK动态代理**: - 当目标对象实现了至少一个接口时,Spring会使用JDK的java.lang.reflect.Proxy类创建一个代理对象。 - 代理对象在调用实际方法...

    Spring AOP完整例子

    在测试方法中,可以注入需要的bean,然后调用方法来触发AOP代理。这样,通知将在适当的时候被调用,我们可以验证其预期行为。 为了更深入地理解这些概念,你可以查看压缩包中的具体代码,例如,`ExampleAspect`类...

Global site tag (gtag.js) - Google Analytics