第三章 AOP 通过Java API创建增强

简介: <h3 lang="zh-CN" class="cjk"><a name="_Toc357859968"></a><span style="font-size:12px; font-family:Calibri,serif"><span lang="en-US"><br></span></span></h3> <h1><span style="font-size:24px"><spa


3.3.1增强类型

前置增强:org.springframework.aop.MethodBeforeAdvice

后置增强:org.springframework.aop.AfterReturningAdvice

环绕增强:org.aopalliance.intercept.MethodInterceptor

异常抛出增强:org.springframework.aop.ThrowsAdvice

引介增强:org.springframework.aop.support.DelegatingIntroductionInterceptor


3.3.2前置增强

就是在连接点方法执行之前执行的内容。
如:我们在UserDaoImpl的save()方法执行之前执行一些内容。

a、UserDaoUserDaoImpl:

[java]  view plain copy print ?
  1. public interface UserDao {    
  2.     public void save();    
  3. }    
[html]  view plain copy print ?
  1. public class UserDaoImpl implements UserDao {    
  2.     public void save() {    
  3.         System.out.println("保存用户...");    
  4.     }    
  5. }    

b、创建一个增强类实现 MethodBeforeAdvice接口
public class UserDaoBeforeAdvice implements MethodBeforeAdvice {
	public void before(Method method, Object[] args, Object object)
			throws Throwable {
		System.out.println("我是前置增强");
	}
}


c、配置
<!-- 把增强类交由spring管理 -->
	<bean id="userDaoBeforeAdvice" class="cn.framelife.spring.advice.UserDaoBeforeAdvice"></bean>

	<!-- 把目标类交由spring管理 -->
	<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	<!-- 
		设置代理类 
		p:target-ref 目标对象
		p:proxyInterfaces 代理所要实现的接口,也就是目标对象的接口
		p:interceptorNames 织入的增强Bean,可以是多个,用","号分开
	-->
	<bean id="adviceUserDao" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="cn.framelife.spring.dao.UserDao"
		p:interceptorNames="userDaoBeforeAdvice"
		p:target-ref="userDao"
	 />

d、main方法中测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		//通过代理来获取userDao对象
		UserDao userDao = (UserDao) context.getBean("adviceUserDao");
		userDao.save();

f、结果
我是前置增强
保存用户...

3.3.3后置增强

就是在连接点方法执行之后执行的内容。

a、UserDaoUserDaoImpl:

[java]  view plain copy print ?
  1. public interface UserDao {    
  2.     public void save();    
  3. }    
[html]  view plain copy print ?
  1. public class UserDaoImpl implements UserDao {    
  2.     public void save() {    
  3.         System.out.println("保存用户...");    
  4.     }    
  5. }    

b、创建一个增强类实现 AfterReturningAdvice接口
public class UserDaoAfterAdvice implements AfterReturningAdvice {
	@Override
	public void afterReturning(Object object, Method method, Object[] args,
			Object arg3) throws Throwable {
		System.out.println("我是后置增强");
	}
}



c、配置
<bean id="userDaoBeforeAdvice" class="cn.framelife.spring.advice.UserDaoBeforeAdvice"></bean>
	<bean id="userDaoAfterAdvice" class="cn.framelife.spring.advice.UserDaoAfterAdvice"></bean>

	<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	
	<bean id="adviceUserDao" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="cn.framelife.spring.dao.UserDao"
		p:interceptorNames="userDaoBeforeAdvice,userDaoAfterAdvice"
		p:target-ref="userDao"
	 />


d、main方法中测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		//通过代理来获取userDao对象
		UserDao userDao = (UserDao) context.getBean("adviceUserDao");
		userDao.save();

f、结果
保存用户...
我是后置增强


3.3.4环绕增强

环绕增强与struts2AOP类似。



a、UserDaoUserDaoImpl:

[java]  view plain copy print ?
  1. public interface UserDao {    
  2.     public void save();    
  3. }    
[html]  view plain copy print ?
  1. public class UserDaoImpl implements UserDao {    
  2.     public void save() {    
  3.         System.out.println("保存用户...");    
  4.     }    
  5. }    

b、创建一个增强类实现 MethodInterceptor接口
public class UserDaoSurroundAdvice implements MethodInterceptor {

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println("环绕增强在方法前执行...");
		Object object = invocation.proceed();
		System.out.println("环绕增强在方法后执行...");
		return object;
	}

}


c、配置
<bean id="userDaoSurroundAdvice" class="cn.framelife.spring.advice.UserDaoSurroundAdvice"></bean>
	
	<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	<bean id="adviceUserDao" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="cn.framelife.spring.dao.UserDao"
		p:interceptorNames=" userDaoSurroundAdvice"
		p:target-ref="userDao"
	 />



d、main方法中测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		//通过代理来获取userDao对象
		UserDao userDao = (UserDao) context.getBean("adviceUserDao");
		userDao.save();

f、结果
环绕增强在方法前执行...
保存用户...
环绕增强在方法后执行...


3.3.5异常抛出增强

就是在方法出现异常之后执行的代码。



a、UserDaoUserDaoImpl:

[java]  view plain copy print ?
  1. public interface UserDao {    
  2.     public void save();    
  3. }    
public class UserDaoImpl implements UserDao {    
     public void save() {    
         System.out.println("保存用户...");    
         //使方法在运行的时候抛出一个异常
          throw new RuntimeException("运行时异常...");

    }    
}  


b、创建一个增强类实现 ThrowsAdvice接口
public class UserDaoThrowsAdvice implements ThrowsAdvice {
	public void afterThrowing(Method method,Object[] args,Object taglet,Exception ex)throws Throwable{
		System.out.println("我是异常抛出接口");
		System.out.println(method.getName());
		System.out.println(ex.getMessage());
	}
}



c、配置
<bean id="userDaoThrowAdvice" class="cn.framelife.spring.advice.UserDaoThrowsAdvice"></bean>

<!--
	 p:proxyTargetClass="false"
	如果目标对象是一个类,而不是一个接口,我们设置为true
-->
	<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	<bean id="adviceUserDao" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="cn.framelife.spring.dao.UserDao"
		p:interceptorNames="userDaoThrowAdvice"
		p:target-ref="userDao"
		p:proxyTargetClass="false"
	 />




d、main方法中测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		//通过代理来获取userDao对象
		UserDao userDao = (UserDao) context.getBean("adviceUserDao");
		userDao.save();

f、结果
保存用户...
Exception in thread "main" java.lang.RuntimeException: 运行时异常...
	at cn.framelife.spring.dao.impl.UserDaoImpl.save(UserDaoImpl.java:12)
	at cn.framelife.spring.dao.impl.UserDaoImpl$$FastClassByCGLIB$$18bd6dee.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
	at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
	at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:124)我是异常抛出接口
save
运行时异常...

	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
	at cn.framelife.spring.dao.impl.UserDaoImpl$$EnhancerByCGLIB$$5bbe38b0.save(<generated>)
	at cn.framelife.spring.test.Test.main(Test.java:17)


3.3.6引介增强

     引介增强是为目标类创建新的方法和属性,引介增强的连接点是类级别的,不是方法级别的。通过引介增强,我们可以为目标类添加一个接口的实现,即原来目标类未实现某个接口,通过引介增强可以为目标类创建实现某个接口的代理。




a、UserDaoUserDaoImpl:

[java]  view plain copy print ?
  1. public interface UserDao {    
  2.     public void save();    
  3. }    
[html]  view plain copy print ?
  1. public class UserDaoImpl implements UserDao {    
  2.     public void save() {    
  3.         System.out.println("保存用户...");    
  4.     }    
  5. }    


b、新建一个接口 AInterface
public interface AInterface {
	public void say();
}



c、增强类继承 DelegatingIntroductionInterceptor实现 AInterface
public class IntroductionAdvice extends DelegatingIntroductionInterceptor implements AInterface {
	/*
	 * 实现AInterface中的方法
	 */
	public void say() {
		System.out.println("UserDao要说话");
	}

	/*
	 * 重写DelegatingIntroductionInterceptor的invoke方法
	 */
	public Object invoke(MethodInvocation mi) throws Throwable {
		System.out.println("方法执行前执行");
		System.out.println(mi.getClass().getName());
		System.out.println(mi.getMethod().getName());
		Object object = super.invoke(mi);
		System.out.println("方法执行后执行");
		return object;
	}	
}




d、配置

<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	<bean id="introductionAdvice" class="cn.framelife.spring.advice.IntroductionAdvice"></bean>
	<!-- 
		代理类设置
		p:proxyTargetClass="true" 引介增强一定要通过创建子类来生成代理,所以要设置为true。
			也不需要配置p:proxyInterfaces目标类的接口
		p:interfaces 引介增强所实现的接口
	 -->
	<bean id="aProxy" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interfaces="cn.framelife.spring.dao.AInterface" 
		p:interceptorNames="introductionAdvice"
		p:target-ref="userDao" 
		p:proxyTargetClass="true" />

e、main方法中测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		UserDao userDao = (UserDao) context.getBean("aProxy");
		userDao.save();
		
		System.out.println("-------------");
		
		AInterface a = (AInterface)userDao;
		a.say();
		
		System.out.println("-------------");
		userDao.save();


f、结果
方法执行前执行
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation
save
保存用户...
方法执行后执行
-------------
方法执行前执行
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation
say
UserDao要说话
方法执行后执行
-------------
方法执行前执行
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation
save
保存用户...
方法执行后执行







目录
相关文章
|
1天前
|
安全 Java API
Java进阶-Java Stream API详解与使用
效、更易于维护的代码,同时享受到函数式编程带来的好处。
9 2
|
1天前
|
Java 大数据 API
利用Java Stream API实现高效数据处理
在大数据和云计算时代,数据处理效率成为了软件开发者必须面对的重要挑战。Java 8及以后版本引入的Stream API为开发者提供了一种声明式、函数式的数据处理方式,极大提升了数据处理的效率和可读性。本文将详细介绍Java Stream API的基本概念、使用方法和性能优势,并通过实际案例展示如何在实际项目中应用Stream API实现高效数据处理。
|
2天前
|
自然语言处理 Java API
Java 8的Stream API和Optional类:概念与实战应用
【5月更文挑战第17天】Java 8引入了许多重要的新特性,其中Stream API和Optional类是最引人注目的两个。这些特性不仅简化了集合操作,还提供了更好的方式来处理可能为空的情况,从而提高了代码的健壮性和可读性。
24 7
|
2天前
|
Java API
Java 8新特性之Lambda表达式与Stream API
【5月更文挑战第17天】本文将介绍Java 8中的两个重要特性:Lambda表达式和Stream API。Lambda表达式是一种新的编程语法,它允许我们将函数作为参数传递给其他方法,从而使代码更加简洁。Stream API是一种用于处理集合的新工具,它提供了一种高效且易于使用的方式来处理数据。通过结合使用这两个特性,我们可以编写出更加简洁、高效的Java代码。
7 0
|
2天前
|
Java
java使用AOP切面获取请求日志并记录
java使用AOP切面获取请求日志并记录
|
4天前
|
Java API
Java 8新特性之Lambda表达式与Stream API实践指南
【5月更文挑战第15天】 随着Java语言的不断发展,Java 8作为一个重要的版本,引入了许多令人兴奋的新特性。其中,Lambda表达式和Stream API是Java 8最受关注的两个特性。本文将深入探讨Lambda表达式的基本概念、语法和使用场景,以及如何结合Stream API实现更加简洁、高效的代码编写。通过实例演示,帮助读者快速掌握这两个新特性,提高Java编程能力。
|
4天前
|
SQL Java API
Java一分钟之-JPA:Java持久化API简介
【5月更文挑战第14天】Java Persistence API (JPA) 是Java的ORM规范,用于简化数据库操作。常见问题包括实体映射、事务管理和性能问题。避免错误的关键在于明确主键策略、妥善使用事务、优化查询及理解实体生命周期。示例展示了如何定义实体和使用`EntityManager`保存数据。JPA通过标准化API让开发者更专注于业务逻辑,提升开发效率和代码维护性。
14 0
|
JSON Java API
Java版阿里云通信短信发送API接口实例(2)
Java版阿里云通信短信发送API接口实例(新)
955 0
|
运维 监控 Java
Java版阿里云通信短信发送API接口实例(1)
Java版阿里云通信短信发送API接口实例(新)
1026 0
Java版阿里云通信短信发送API接口实例(1)
|
Java API 开发工具
Java版阿里云通信短信发送API接口实例(新)
版权声明:欢迎转载,请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/78751698 阿里云通信(原名阿里大于)的短信服务(Short Message Service)是阿里云为用户提供的一种通信服务的能力,支持快速发送短信验证码、短信通知等。
3425 0