现在的位置: 首页 > 综合 > 正文

spring_aop应用

2017年12月27日 ⁄ 综合 ⁄ 共 6577字 ⁄ 字号 评论关闭

aop-链接:http://pandonix.iteye.com/blog/336873

链接: http://z-xiaofei168.iteye.com/blog/1040231

 Spring中AOP代理由Spring的IoC容器负责生成,管理,其依赖关系也由IoC容器负责管理。因此AOP代理可以直接使用容器中的其他Bean实例作为目标,这种关系可由Ioc容器的依赖注入提供。

Spring AOP采用基于代理的AOP实现方案,AspectJ则采用编译时增强的解决方案。

 

Spring AOP应用:

方式一:采用Annotation注解方式实现

---定义切面Bean:

@Aspect
public class AspectTest
{
   //定义类的其他类容
      ......
}

当我们使用 @Aspect 来修饰一个 Java 类之后,Spring 将不会把该 Bean 当成组件 Bean 处理,因此负责自动增强的后处理 Bean 将会略过该 Bean,不会对该 Bean 进行任何增强处理。

开发时无须担心使用 @Aspect 定义的方面类被增强处理,当 Spring 容器检测到某个 Bean 类使用了 @Aspect 标注之后,Spring 容器不会对该 Bean 类进行增强。

 

---定义Before增强处理

  使用@Before来标注一个方法,使该方法作为一个Before增强处理。使用@Before标注时,通常需要指定一个value值,改值指定一个切入表达式,用于指定该增强处理将被织入哪些切入点。

<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context-3.0.xsd


http://www.springframework.org/schema/aop

	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
	<!-- 指定自动搜索Bean组件、自动搜索切面类 -->
	<context:component-scan base-package="org.crazyit.app.service
		,org.crazyit.app.advice">
		<context:include-filter type="annotation"
			expression="org.aspectj.lang.annotation.Aspect"/>
	</context:component-scan>
	<!-- 启动@AspectJ支持 -->
	<aop:aspectj-autoproxy/>
</beans>
@Aspect
public class BeforeAdviceTest
{
	//匹配org.crazyit.app.service.impl包下所有类的、
	//所有方法的执行作为切入点
	@Before("execution(* org.crazyit.app.service.impl.*.*(..))")
	public void authority()
	{
		System.out.println("模拟执行权限检查");
	}
}

定义AfterThrowing 增强处理

@Aspect
public class AfterThrowingAdviceTest
{
	//匹配org.crazyit.app.service.impl包下所有类的、
	//所有方法的执行作为切入点
	@AfterThrowing(throwing="ex"
		, pointcut="execution(* org.crazyit.app.service.impl.*.*(..))")
	public void doRecoveryActions(Throwable ex)
	{
		System.out.println("目标方法中抛出的异常:" + ex);
		System.out.println("模拟抛出异常后的增强处理...");
	}
}

---定义AfterReturning增强处理

---定义After 增强处理

---定义Around 增强处理

---访问目标方法的参数:访问目标方法的做法是定义增强处理时将第一个参数定义为JoinPoint类型,当该增强处理方法被调用时,该JoinPoint 参数就代表了织入增强处理的连接点。

@Aspect
public class FourAdviceTest
{
	//定义Around增强处理执行
	@Around("execution(* org.crazyit.app.service.impl.*.*(..))")
	public Object processTx(ProceedingJoinPoint jp)
		throws java.lang.Throwable
	{
		System.out.println("Around增强:执行目标方法之前,模拟开始事务...");
		//访问执行目标方法的参数
		Object[] args = jp.getArgs();
		//当执行目标方法的参数存在,
		//且第一个参数是字符串参数
		if (args != null && args.length > 0
			&& args[0].getClass() == String.class)
		{
			//改变第一个目标方法的第一个参数
			args[0] = "被改变的参数";
		}
		//执行目标方法,并保存目标方法执行后的返回值
		Object rvt = jp.proceed(args);
		System.out.println("Around增强:执行目标方法之后,模拟结束事务...");
		return rvt + " 新增的内容";
	}
	
	//定义Before增强处理执行
	@Before("execution(* org.crazyit.app.service.impl.*.*(..))")
	public void authority(JoinPoint jp)
	{
		System.out.println("Before增强:模拟执行权限检查");
		//返回被织入增强处理的目标方法
		System.out.println("Before增强:被织入增强处理的目标方法为:"
			+ jp.getSignature().getName());
		//访问执行目标方法的参数
		System.out.println("Before增强:目标方法的参数为:"
			+ Arrays.toString(jp.getArgs()));
		//访问被增强处理的目标对象
		System.out.println("Before增强:被织入增强处理的目标对象为:"
			+ jp.getTarget());
	}
	
	//定义AfterReturning增强处理执行
	@AfterReturning(pointcut="execution(* org.crazyit.app.service.impl.*.*(..))"
		, returning="rvt")
	public void log(JoinPoint jp , Object rvt)
	{
		System.out.println("AfterReturning增强:获取目标方法返回值:" 
			+ rvt);
		System.out.println("AfterReturning增强:模拟记录日志功能...");
		//返回被织入增强处理的目标方法
		System.out.println("AfterReturning增强:被织入增强处理的目标方法为:"
			+ jp.getSignature().getName());
		//访问执行目标方法的参数
		System.out.println("AfterReturning增强:目标方法的参数为:"
			+ Arrays.toString(jp.getArgs()));
		//访问被增强处理的目标对象
		System.out.println("AfterReturning增强:被织入增强处理的目标对象为:"
			+ jp.getTarget());
	}

	//定义After增强处理执行
	@After("execution(* org.crazyit.app.service.impl.*.*(..))")
	public void release(JoinPoint jp)
	{
		System.out.println("After增强:模拟方法结束后的释放资源...");
		//返回被织入增强处理的目标方法
		System.out.println("After增强:被织入增强处理的目标方法为:"
			+ jp.getSignature().getName());
		//访问执行目标方法的参数
		System.out.println("After增强:目标方法的参数为:"
			+ Arrays.toString(jp.getArgs()));
		//访问被增强处理的目标对象
		System.out.println("After增强:被织入增强处理的目标对象为:"
			+ jp.getTarget());
	}
}

---定义切入点:

  为一个切入表达式起一个名称,从而允许在多个增强处理中重用该名称。SpringAOP只支持以SpringBean的方法执行组作为连接点,所以可以把切入点看错所有能和切入表达式匹配的Bean方法。

//1.
@Aspect
public class SystemArchitecture 
{
	@Pointcut("execution(* org.crazyit.app.service"
		+ ".impl.Chin*.say*(..))")
	public void myPointcut()
	{
	}
}
//2.
@Aspect
public class LogAspect
{
	//直接使用SystemArchitecture切面类的myPointcut切入点
	//args(msg)保证该切入点只匹配只有一个字符串参数的方法
	@AfterReturning(pointcut="SystemArchitecture.myPointcut()"
		+ "&&args(msg)" , returning="retVal")
	public void writeLog(String msg, Object retVal)
	{
		System.out.println(msg);
		System.out.println(retVal);
		System.out.println("模拟记录日志....");
	}
}

方式二:采用XML方式配置

//Xml配置aop
<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd


http://www.springframework.org/schema/aop

	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
	<aop:config>
		<!-- 将fourAdviceBean转换成切面Bean,切面Bean的新名称为:fourAdviceAspect-->
		<aop:aspect id="fourAdviceAspect" ref="fourAdviceBean">
			<!-- 定义一个After增强处理,
				直接指定切入点表达式
				以切面Bean中的release()方法作为增强处理方法 -->
			<aop:after pointcut="execution(* org.crazyit.app.service.impl.*.*(..))" 
				method="release"/>
			<!-- 定义一个Before增强处理,
				直接指定切入点表达式
				以切面Bean中的authority()方法作为增强处理方法 -->
			<aop:before pointcut="execution(* org.crazyit.app.service.impl.*.*(..))" 
				method="authority"/>
			<!-- 定义一个AfterReturning增强处理,
				直接指定切入点表达式
				以切面Bean中的log()方法作为增强处理方法 -->
			<aop:after-returning pointcut="execution(* org.crazyit.app.service.impl.*.*(..))" 
				method="log" returning="rvt"/>
			<!-- 定义一个Around增强处理,
				直接指定切入点表达式
				以切面Bean中的processTx()方法作为增强处理方法 -->
			<aop:around pointcut="execution(* org.crazyit.app.service.impl.*.*(..))" 
				method="processTx"/>
		</aop:aspect>		
	</aop:config>
	<!-- 定义一个普通组件Bean -->
	<bean id="chinese" 
	class="org.crazyit.app.service.impl.Chinese"/>
	<!-- 定义一个普通Bean实例,该Bean实例将被作为Aspect Bean -->
	<bean id="fourAdviceBean"
	class="org.crazyit.app.advice.FourAdviceTest"/>	
</beans>

//XML配置PointCut
	<aop:config>
		<!-- 定义一个切入点:myPointcut,直接指定它对应的切入点表达式 -->
		<aop:pointcut id="myPointcut" 
			expression="execution(* org.crazyit.app.service.impl.*.*(..))"/>
		<aop:aspect id="afterThrowingAdviceAspect"
			ref="afterThrowingAdviceBean" order="1">
			<!-- 定义一个AfterThrowing增强处理,指定切入点
				以切面Bean中的doRecoveryActions()方法作为增强处理方法 -->
			<aop:after-throwing pointcut-ref="myPointcut" 
				method="doRecoveryActions" throwing="ex"/>
		</aop:aspect>
	</aop:config>
	<!-- 再定义一个普通Bean实例,该Bean实例将被作为Aspect Bean -->
	<bean id="afterThrowingAdviceBean"
	class="org.crazyit.app.advice.AfterThrowingAdviceTest"/>

注:摘自轻量级JavaEE企业应用实战第三版

抱歉!评论已关闭.