java spring总结-AOP

时间:2025-08-27 15:24:02来源:互联网

下面小编就为大家分享一篇java spring总结-AOP,具有很好的参考价值,希望对大家有所帮助。

Aop(面向切面编程)

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程

切面:切面是一个类如:事务、日志、安全性的框架,权限等类就是切面

通知:切面中的方法就是通知

连接点:客户端调用的方法就是连接点

切入点:只有符合切入点的条件,才能让通知和目标方法结合在一起,满足一定条件才会执行目标方法,这里的条件表达式就是切入点

目标对象:目标对象就是被代理对象也就是target

AOP代理:AOP代理就是代理对象

织入:形成代理对象方法体的过程

意义:

说明:

  • 在开发的过程中,事务、日志、权限、安全性的框架、目标方法完全是松耦合的
  • 在形成代理对象的方法的过程中就把这几个结合在一起了

 

代理模式

静态代理模式

代理类程序员自己写。

代理类和被代理类实现同一个接口,代理类调用被代理类方法,并提供额外的方法。

动态代理模式

程序运行时,运用反射机制生成代理类。

Jdk动态代理

接口

目标类

拦截器

拦截器对象是动态代理要用到的一个参数,实现对松耦合的对象中的方法进行有序排列调用

target参数代表被代理对象,也就是实现类

客户端

public class PersonDaoTest {
		public void testJDKProxy(){
		Object target = new PersonDaoImpl();
		Transaction transaction = new Transaction();
		/**
		 *  创建一个拦截器
		 */
PersonDaoInterceptor interceptor = new PersonDaoInterceptor(target, transaction);
		/**
		 * 1、目标类的类加载器
		 * 2、目标类实现的所有的接口
		 * 3、拦截器
		 */
		PersonDao personDao = (PersonDao)Proxy.newProxyInstance(
					target.getClass().getClassLoader(), 
					target.getClass().getInterfaces(), interceptor);
		personDao.savePerson();
	}}
问题
  • 代理对象有多少方法,方法的名称是什么?

因为代理对象和目标类一样,同样的实现了接口,所以接口中有多少方法,代理对象中就有多少个方法,名称和接口中的方法的名称一样。

  • 拦截器中的invoke方法在什么时候执行的?

当在客户端,代理对象调用方法的时候,进入到了invoke方法

  • 拦截器中的invoke方法中的method参数在什么时候传递的值?

当在客户端,代理对象调用方法的时候,进入到了invoke方法,这个时候,method参数就是代理对象调用的方法。

  • 代理对象的方法体的内容是什么?

代理对象的方法体的内容就是invoke方法体的内容

代理对象的方法体:

  • 开启事务
  • 目标方法
  • 事务的提交
  • 代理对象的方法体就把事务和目标方法结合在一起了,这样做的目的就是为了让目标类的目标方法和事务的方法松耦合。

流程图

作用:把目标类和事务松耦合。

Cglib代理:基于子类的动态代理

没有接口

  • 产生的代理类是目标类的子类
  • 是用字节码增强技术产生的代理类

 PersonDaoImpl.java

public class PersonDaoImpl{
	public void savePerson() {
		System.out.println("save person");
	}
	public void updatePerson(){
		System.out.println("update person");
	}}

PersonDaoInterceptor.java

public class PersonDaoInterceptor implements MethodInterceptor{
	private Object target;
	private Transaction transaction;
	
	/**
	 * 产生代理类
	 * @return
	 */
	public Object createProxy(){
		Enhancer enhancer = new Enhancer();
		//设置代理类的父类是目标类
		enhancer.setSuperclass(target.getClass());
		enhancer.setCallback(this);
		return enhancer.create();}
	
	public PersonDaoInterceptor(Object target, Transaction transaction) {
		this.target = target;
		this.transaction = transaction;
	}
	
	public Object intercept(Object arg0, Method method, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		if(method.getName().equals("savePerson")
				||method.getName().equals("updatePerson")){
			this.transaction.beginTransaction();
			method.invoke(target, arg2);
			this.transaction.commit();
		}else{
			method.invoke(target, arg2);
		}
		return null;
	}}

PersonDaoTest.java

public class PersonDaoTest {
	@Test
	public void testJDKProxy(){
		Object target = new PersonDaoImpl();
		Transaction transaction = new Transaction();
		/**
		 *  创建一个拦截器
		 */
		PersonDaoInterceptor interceptor = new PersonDaoInterceptor(target, transaction);
		
		PersonDaoImpl proxy = (PersonDaoImpl)interceptor.createProxy();
		proxy.savePerson();
	}
}

aop使用实例

目标接口

目标类

切面

Spring的配置文件

执行流程

说明:

  • getBean时,如果该类没有生成代理对象(如:xml中切入点表达式没有包含目标类),则返回对象本身

getBean的参数在xml中对应的类就是目标类

  • 如果产生了代理对象,则返回代理对象
  • 如果目标类实现了接口,则采用jdkproxy生成代理对象,如果目标类没有实现接口,则采用cglibproxy生成代理对象,而生成代理对象是由spring容器内部完成的。

切入点表达式

后面有问号的内容代表可以不写

一个*代表该位置任意类型,..代表任意类型的任意个数参数代表所有的公共方法,一个.代表该位置有一个或多个任意类型

代表所有的以set开头的方法

代表com.xyz.service包下的AccoutService类的所有的方法

代表com.xyz.service包下的所有的类的所有的方法

代表com.xyz.service包及子包下的所有的类的所有的方法

代表com.itheima.spring.aop.xml包下的所有的类的有三个参数,第一个参数为Long,第二个参数为String,第三个参数为任意类型的所有的方法

通知

前置通知

在目标方法执行之前执行。

前置通知也可以是无参方法,其他通知也是

后置通知

在目标方法执行之后执行,可以获取目标方法的返回值,当目标方法遇到异常,不执行

最终通知

无论目标方法是否遇到异常都会执行,相当于代码中的finally

异常通知

获取目标方法抛出的异常

环绕通知

能够控制目标方法的执行

输出aaa,执行前置通知,执行目标方法(如果有异常,执行异常通知),执行后置通知,执行最终通知,输出bbb

如果joinPoint.proceed()方法不写,则环绕通知就不会执行

本站部分内容转载自互联网,如果有网站内容侵犯了您的权益,可直接联系我们删除,感谢支持!