切面类:
package com.atChina.Test2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* @Aspect:来自aspectj框架,表示当前类是切面类
* 切面类是用来给业务方法增强功能的类
*/
@Aspect
public class MyAspect {
/**
* @AfterReturning:后置通知,在目标方法之后调用
* 属性:1. value,表示切入点表达式(切面功能加入的位置)
* 2. returning,自定义变量名,表示目标方法的返回值.自定义的变量名需要和通知方法的参数名一样
* 位置:在方法的上面
*
* 后置通知的特点:
* 1.在目标方法之后执行
* 2.能够获取目标方法的执行结果,并且还可以对执行结果进行修改
* 1).目标方法返回值是简单类型(String和java基本数据类型),在通知方法中修改返回值不会影响目标方法的最终结果
* 2).目标方法返回值是非简单类型,在通知方法中修改返回值的属性值,这样就会影响目标方法的最终结果
* 3.不会影响目标方法的执行
*
*/
/*
* Object result = Student getStudent() 返回值是字符串
* afterStudent(result); // 参数传递的是值
*
* 后置通知方法中也可以有JoinPoint参数,如果通知方法中有多个参数,JoinPoint一定是第一个参数
*/
@AfterReturning(value="execution(* *..SomeServiceImpl.do*(..))", returning="result")
public void afterFunc(JoinPoint jp, Object result){
System.out.println("获取切入点的方法名称:"+jp.getSignature().getName());
if(result instanceof String){
result = ((String)result).toUpperCase();
}
System.out.println("目标方法的返回值result:"+result);
System.out.println("执行了后置通知......");
}
/*
* Object result = Student getStudent() 返回值是对象
* afterStudent(result); // 参数传递的是引用
*/
@AfterReturning(value="execution(* *..SomeServiceImpl.get*(..))", returning="result")
public void afterStudent(Object result){
if(result != null){
Student st = (Student)result;
st.setAge(21);
st.setName("八戒");
}
System.out.println("执行了后置通知......");
}
}
普通bean
package com.atChina.Test2;
public interface SomeService {
public void doSome();
public String doOther(String params);
public Student getStudent();
}
package com.atChina.Test2;
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;
}
}
package com.atChina.Test2;
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.Test2.SomeServiceImpl" />
<!-- 声明切面类对象 -->
<bean id="myAspect" class="com.atChina.Test2.MyAspect" />
<!-- 声明自动代理生成器,创建代理对象 -->
<aop:aspectj-autoproxy /> <!-- 寻找aspectj框架能够识别的标签 -->
</beans>
测试类以及测试结果:
@Test
public void test1(){
String configLocation = "com/atChina/Test2/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.doOther("taimxai");
System.out.println("返回值result:"+result);
System.out.println("===================================");
Student st = proxy.getStudent();
System.out.println("返回值result:"+st);
}
测试结果:
com.sun.proxy.$Proxy8
===================================
执行了doSome业务方法...taimxai
获取切入点的方法名称:doOther
目标方法的返回值result:TAIMXAI
执行了后置通知......
返回值result:taimxai
===================================
执行了后置通知......
返回值result:Student [name=八戒, age=21]