切面类:
package com.atChina.Test3;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* @Aspect:来自aspectj框架,表示当前类是切面类
* 切面类是用来给业务方法增强功能的类
*/
@Aspect
public class MyAspect {
/**
* @Around:环绕通知,在目标方法前和后都能增强功能
* 属性: value,表示切入点表达式(切面功能加入的位置)
* 位置:在方法的上面
*
* 后置通知的特点:
* 1.在目标方法前和后都能增强功能
* 2.能够修改目标方法的执行结果
* 3.能够控制目标方法是否执行
*
* 参数 ProceedingJoinPoint 继承自org.aspectj.lang.JoinPoint,表示切入点
*
* 返回值: Object,表示目标方法的执行结果
*/
@Around(value="execution(* *..SomeServiceImpl.doAround(..))")
public Object myAround(ProceedingJoinPoint pjp) throws Throwable{
Object result=null;
System.out.println("环绕通知,在目标方法之前...增强功能");
result = pjp.proceed(); // 执行目标方法, 注释该语句后,目标方法就不会被执行,从而控制了目标方法的执行
if(null != result){
// 修改目标方法的执行结果
result = ((String)result).toUpperCase();
}
System.out.println("环绕通知,在目标方法之后...增强功能");
return result;
}
}
普通bean
package com.atChina.Test3;
public interface SomeService {
public void doSome();
public String doOther(String params);
public Student getStudent();
public String doAround();
}
package com.atChina.Test3;
public class SomeServiceImpl implements SomeService {
@Override
public void doSome() {
System.out.println("执行了doSome业务方法...");
}
@Override
public String doOther(String params) {
// TODO Auto-generated method stub
System.out.println("执行了doSome业务方法..."+params);
return params;
}
@Override
public Student getStudent() {
Student st = new Student();
st.setAge(22);
st.setName("孙悟空");
return st;
}
@Override
public String doAround() {
System.out.println("执行了doAround业务方法...");
return "doAround";
}
}
package com.atChina.Test3;
public class Student {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
配置bean以及声明自定代理生成器
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引用Spring的多个Schema空间的格式定义文件 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd ">
<!-- 声明目标类对象 -->
<bean id="someService" class="com.atChina.Test3.SomeServiceImpl" />
<!-- 声明切面类对象 -->
<bean id="myAspect" class="com.atChina.Test3.MyAspect" />
<!-- 声明自动代理生成器,创建代理对象 -->
<aop:aspectj-autoproxy /> <!-- 寻找aspectj框架能够识别的标签 -->
</beans>
测试类以及测试结果:
@Test
public void test1(){
String configLocation = "com/atChina/Test3/applicationContext.xml"; // 类路径的根目录
ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocation);
// 目标对象有接口,aspectj默认使用的是jdk动态代理
SomeService proxy = (SomeService) ctx.getBean("someService");
System.out.println(proxy.getClass().getName());
// proxy.doSome();
System.out.println("===================================");
String result = proxy.doAround();
System.out.println("返回值result:"+result);
}
测试结果:
com.sun.proxy.$Proxy8
===================================
环绕通知,在目标方法之前...增强功能
执行了doAround业务方法...
环绕通知,在目标方法之后...增强功能
返回值result:DOAROUND