l 切面类Security
/**切面*/
public class Security {
/**通知*/
/**
* 任何通知方法可以将第一个参数定义为org.aspectj.lang.JoinPoint类型 (
* 环绕通知需要定义第一个参数为ProceedingJoinPoint类型, 它是 JoinPoint 的一个子类)。
* JoinPoint 接口提供了一系列有用的方法,
* 比如 getArgs()(返回方法参数)、
* getThis()(返回代理对象)、
* getTarget()(返回目标)、
* getSignature()(返回正在被通知的方法相关信息)、
* toString() (打印出正在被通知的方法的有用信息)。
*/
public void checkSecurity(JoinPoint joinPoint,Object returnValue){
System.out.println("正在执行验证...");
Object [] args = joinPoint.getArgs();
if(args!=null && args.length>0){
for(Object o:args){
System.out.println("参数:"+o);
}
}
System.out.println("代理对象:"+joinPoint.getThis().getClass());
System.out.println("目标对象:"+joinPoint.getTarget().getClass());
System.out.println("访问目标对象方法的名称:"+joinPoint.getSignature().getName());
System.out.println("spring容器中定义切入点的表达式:"+joinPoint.toString());
System.out.println("目标对象方法的返回值:"+returnValue);
}
}
l Spring容器(beans.xml)
<?xml version="1.0" encoding="UTF-8"?>
<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 id="userServiceImpl" class="cn.itcast.e_xml.b_afterReturning.UserServiceImpl"></bean>
<!-- 声明切面 (无灵魂)-->
<bean id="security" class="cn.itcast.e_xml.b_afterReturning.Security"></bean>
<aop:config>
<aop:aspect id="aa" ref="security">
<aop:pointcut id="save" expression="execution(* cn.itcast.e_xml.b_afterReturning.UserServiceImpl.saveUser(..))" />
<aop:pointcut id="find" expression="execution(* cn.itcast.e_xml.b_afterReturning.UserServiceImpl.findUser(..))" />
<!--
后置通知:在访问目标对象方法之后,再执行通知定义的方法
特点:1:如果在目标对象中抛出异常,此时不会执行通知
2:因为是先执行目标对象中的方法,再执行通知,所以能不能在通知中获取目标对象的方法的返回值?能
第一步:在spring容器中定义:returning="returnValue"
第二步:在通知的方法中的第二个参数,可以指定Object类型,
例如public void checkSecurity(JoinPoint joinPoint,Object returnValue){
总结: 参数一定要放在到第二个参数的位置
参数一定一个Object类型
参数的属性名称一定要与spring容器中定义的returning相一致
-->
<aop:after-returning pointcut-ref="save" method="checkSecurity" returning="returnValue"/>
<aop:after-returning pointcut-ref="find" method="checkSecurity" returning="returnValue"/>
</aop:aspect>
</aop:config>
</beans>
l 切面类Security
/**切面*/
public class Security {
/**通知*/
/**
* 任何通知方法可以将第一个参数定义为org.aspectj.lang.JoinPoint类型 (
* 环绕通知需要定义第一个参数为ProceedingJoinPoint类型, 它是 JoinPoint 的一个子类)。
* JoinPoint 接口提供了一系列有用的方法,
* 比如 getArgs()(返回方法参数)、
* getThis()(返回代理对象)、
* getTarget()(返回目标)、
* getSignature()(返回正在被通知的方法相关信息)、
* toString() (打印出正在被通知的方法的有用信息)。
*/
public void checkSecurity(JoinPoint joinPoint,Throwable throwingValue){
System.out.println("正在执行验证...");
Object [] args = joinPoint.getArgs();
if(args!=null && args.length>0){
for(Object o:args){
System.out.println("参数:"+o);
}
}
System.out.println("代理对象:"+joinPoint.getThis().getClass());
System.out.println("目标对象:"+joinPoint.getTarget().getClass());
System.out.println("访问目标对象方法的名称:"+joinPoint.getSignature().getName());
System.out.println("spring容器中定义切入点的表达式:"+joinPoint.toString());
System.out.println("目标对象方法抛出的异常是:"+throwingValue);
}
}
l Spring容器(beans.xml)
<?xml version="1.0" encoding="UTF-8"?>
<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 id="userServiceImpl" class="cn.itcast.e_xml.c_afterThrowing.UserServiceImpl"></bean>
<!-- 声明切面 (无灵魂)-->
<bean id="security" class="cn.itcast.e_xml.c_afterThrowing.Security"></bean>
<aop:config>
<aop:aspect id="aa" ref="security">
<aop:pointcut id="save" expression="execution(* cn.itcast.e_xml.c_afterThrowing.UserServiceImpl.saveUser(..))" />
<aop:pointcut id="find" expression="execution(* cn.itcast.e_xml.c_afterThrowing.UserServiceImpl.findUser(..))" />
<!--
异常通知:在访问目标对象方法之后,前提是目标对象方法中抛出异常,此时才会执行通知定义的方法
特点:1:只有目标对象方法中抛出异常,此时才会执行通知
2:在通知的方法中捕获异常
第一步:在spring容器中定义
第二步:在通知的方法中的第二个参数的位置,可以指定,例如public void checkSecurity(JoinPoint joinPoint,Throwable throwingValue){
* 要求一:获取目标对象抛出的异常的参数要放置在第二个参数的位置
* 要求二:类型必须指定Throwable类型
* 要求三:Throwable对应的属性值要和spring容器中定义的throwing="throwingValue"值要相匹配
-->
<aop:after-throwing pointcut-ref="save" method="checkSecurity" throwing="throwingValue"/>
<aop:after-throwing pointcut-ref="find" method="checkSecurity" throwing="throwingValue"/>
</aop:aspect>
</aop:config>
</beans>
l 切面类Security
/**切面*/
public class Security {
/**通知*/
/**
* 任何通知方法可以将第一个参数定义为org.aspectj.lang.JoinPoint类型 (
* 环绕通知需要定义第一个参数为ProceedingJoinPoint类型, 它是 JoinPoint 的一个子类)。
* JoinPoint 接口提供了一系列有用的方法,
* 比如 getArgs()(返回方法参数)、
* getThis()(返回代理对象)、
* getTarget()(返回目标)、
* getSignature()(返回正在被通知的方法相关信息)、
* toString() (打印出正在被通知的方法的有用信息)。
*/
public void checkSecurity(JoinPoint joinPoint){
System.out.println("正在执行验证...");
Object [] args = joinPoint.getArgs();
if(args!=null && args.length>0){
for(Object o:args){
System.out.println("参数:"+o);
}
}
System.out.println("代理对象:"+joinPoint.getThis().getClass());
System.out.println("目标对象:"+joinPoint.getTarget().getClass());
System.out.println("访问目标对象方法的名称:"+joinPoint.getSignature().getName());
System.out.println("spring容器中定义切入点的表达式:"+joinPoint.toString());
}
}
l Spring容器(beans.xml)
<?xml version="1.0" encoding="UTF-8"?>
<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 id="userServiceImpl" class="cn.itcast.e_xml.d_after.UserServiceImpl"></bean>
<!-- 声明切面 (无灵魂)-->
<bean id="security" class="cn.itcast.e_xml.d_after.Security"></bean>
<aop:config>
<aop:aspect id="aa" ref="security">
<aop:pointcut id="save" expression="execution(* cn.itcast.e_xml.d_after.UserServiceImpl.saveUser(..))" />
<aop:pointcut id="find" expression="execution(* cn.itcast.e_xml.d_after.UserServiceImpl.findUser(..))" />
<!--
最终通知:在访问目标对象方法之后,不管是否抛出异常,此时都会执行通知定义的方法
特点:1:不管目标对象是否抛出异常,都会执行通知的方法
-->
<aop:after pointcut-ref="save" method="checkSecurity"/>
<aop:after pointcut-ref="find" method="checkSecurity"/>
</aop:aspect>
</aop:config>
</beans>
l 切面类Security
/**切面*/
public class Security {
/**通知*/
/**
* 普通通知类型:
* 任何通知方法可以将第一个参数定义为org.aspectj.lang.JoinPoint类型 (
* 环绕通知需要定义第一个参数为ProceedingJoinPoint类型, 它是 JoinPoint 的一个子类)。
* JoinPoint 接口提供了一系列有用的方法,
* 比如 getArgs()(返回方法参数)、
* getThis()(返回代理对象)、
* getTarget()(返回目标)、
* getSignature()(返回正在被通知的方法相关信息)、
* toString() (打印出正在被通知的方法的有用信息)。
*
* 环绕通知类型
* 通知的第一个参数必须是 ProceedingJoinPoint类型。
* 在通知体内,调用 ProceedingJoinPoint的proceed()方法会导致 后台的连接点方法执行。
* proceed 方法也可能会被调用并且传入一个 Object[]对象-该数组中的值将被作为方法执行时的参数。
*
* 环绕通知将通知的方法的返回值要定义成Object类型,只有这样才能将目标对象方法的返回值,传递给客户端
*/
public Object checkSecurity(ProceedingJoinPoint joinPoint){
//如果调用joinPoint.proceed();方法放置在通知的最前面,此时就相当于后置通知
Object value = null;
try {
value = joinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("正在执行验证...");
Object [] args = joinPoint.getArgs();
if(args!=null && args.length>0){
for(Object o:args){
System.out.println("参数:"+o);
}
}
System.out.println("代理对象:"+joinPoint.getThis().getClass());
System.out.println("目标对象:"+joinPoint.getTarget().getClass());
System.out.println("访问目标对象方法的名称:"+joinPoint.getSignature().getName());
System.out.println("spring容器中定义切入点的表达式:"+joinPoint.toString());
// //如果调用joinPoint.proceed();方法放置在通知的最后,此时就相当于前置通知
// Object value = null;
// try {
// value = joinPoint.proceed();
// } catch (Throwable e) {
// e.printStackTrace();
// }
return value;
}
}
l Spring容器(beans.xml)
<?xml version="1.0" encoding="UTF-8"?>
<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 id="userServiceImpl" class="cn.itcast.e_xml.e_around.UserServiceImpl"></bean>
<!-- 声明切面 (无灵魂)-->
<bean id="security" class="cn.itcast.e_xml.e_around.Security"></bean>
<aop:config>
<aop:aspect id="aa" ref="security">
<aop:pointcut id="save" expression="execution(* cn.itcast.e_xml.e_around.UserServiceImpl.saveUser(..))" />
<aop:pointcut id="find" expression="execution(* cn.itcast.e_xml.e_around.UserServiceImpl.findUser(..))" />
<!--
环绕通知:
最后一种通知是环绕通知。环绕通知在一个目标对象方法执行之前和之后执行。
它使得通知有机会 在一个方法执行之前和执行之后运行。而且它可以决定这个方法在什么时候执行,如何执行,甚至是否执行。
环绕通知经常在某线程安全的环境下,你需要在一个方法执行之前和之后共享某种状态的时候使用。
请尽量使用最简单的满足你需求的通知。(比如如果简单的前置通知也可以适用的情况下不要使用环绕通知)。
-->
<aop:around pointcut-ref="save" method="checkSecurity"/>
<aop:around pointcut-ref="find" method="checkSecurity"/>
</aop:aspect>
</aop:config>
</beans>