public class Transaction {
/**
* 前置通知
* 通过JoinPoint获取连接点的信息
*/
public void beginTransaction(JoinPoint joinPoint){
joinPoint.getArgs();//获取方法的参数
String methodName = joinPoint.getSignature().getName();
System.out.println(methodName);
System.out.println("begin transaction");
}
/**
* 后置通知
*/
public void commit(JoinPoint joinPoint,Object val){
List<Person> personList = (List<Person>)val;
System.out.println(personList.size());
System.out.println("commit");
}
/**
* 最终通知
*/
public void finallyMethod(){
System.out.println("finally method");
}
/**
* 异常通知
*/
public void exceptionMethod(Throwable ex){
System.out.println(ex.getMessage());
}
/**
* 环绕通知
* 能控制目标方法的执行
* @param joinPoint
* @throws Throwable
*/
public void aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("aaaa");
String methodName = joinPoint.getSignature().getName();
if("savePerson".equals(methodName)){
joinPoint.proceed();
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<!--
1、引入AOP的命名空间
2、目标类
3、切面
4、拦截器 由spring内部实现
5、aop的配置
-->
<bean id="personDao" class="cn.itcast.spring0909.aop.xml.PersonDaoImpl"></bean>
<bean id="transaction" class="cn.itcast.spring0909.aop.xml.Transaction"></bean>
<!--
aop的配置
-->
<aop:config>
<!--
切入点表达式
expression
确定哪个类可以生成代理对象
id 唯一标识
-->
<aop:pointcut expression="execution(* cn.itcast.spring0909.aop.xml.PersonDaoImpl.*(..))" id="perform"/>
<!--
切面
-->
<aop:aspect ref="transaction">
<!--
前置通知
* 在目标方法执行之前
*
-->
<!--
<aop:before method="beginTransaction" pointcut-ref="perform"/>
-->
<!--
后置通知
* 在目标方法执行之后
* 可以根据returning获取目标方法的返回值
* 如果目标方法遇到异常,该通知不执行
-->
<!--
<aop:after-returning method="commit" pointcut-ref="perform" returning="val"/>
-->
<!--
前置通知和后置通知只能在目标方法文中添加内容,但是控制不了目标方法的执行
-->
<!--
最终通知
* 在目标方法执行之后
* 无论目标方法是否遇到异常,都执行
* 经常做一些关闭资源
-->
<!--
<aop:after method="finallyMethod" pointcut-ref="perform"/>
-->
<!--
异常通知
目的就是为了获取目标方法抛出的异常
-->
<aop:after-throwing method="exceptionMethod" throwing="ex" pointcut-ref="perform"/>
<!--
环绕通知
能控制目标方法的执行
-->
<aop:around method="aroundMethod" pointcut-ref="perform"/>
</aop:aspect>
</aop:config>
</beans>
* 说明:
* 如果目标类实现了接口,则spring容器会采用jdkproxy,如果目标类没有实现接口,则spring容器会采用
* cglibproxy
public class PersonDaoImpl{
public void savePerson() {
System.out.println("save person");
}
public void updatePerson() {
System.out.println("update person");
}
public void deletePerson() {
System.out.println("delete person");
}
public List<Person> getPerson() {
// TODO Auto-generated method stub
Person person = new Person();
person.setPid(1L);
person.setPname("aaa");
List<Person> personList = new ArrayList<Person>();
personList.add(person);
for(Person person2:personList){
System.out.println(person2.getPname());
}
return personList;
}
}
* 说明:
* 如果目标类实现了接口,则spring容器会采用jdkproxy,如果目标类没有实现接口,则spring容器会采用
* cglibproxy
* @author Administrator
*
*/
public class PersonTest extends SpringHelper{
static{
path = "cn/itcast/spring0909/aop/xml/applicationContext.xml";
}
@Test
public void test(){
PersonDaoImpl personDao = (PersonDaoImpl)context.getBean("personDao");
personDao.savePerson();
}
}
这里被多次代理 会出错
另一个例子
public class Logger {
public void logging(){
System.out.println("logging");
}
}
public class Privilege {
public void privilege(){
System.out.println("privilege");
}
}
public class Security {
public void security(){
System.out.println("security");
}
}
public class SalaryManager {
public void showSalary(){
System.out.println("正在查看工资");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<bean id="logger" class="cn.itcast.spring0909.aop.xml.salary.Logger"></bean>
<bean id="privilege" class="cn.itcast.spring0909.aop.xml.salary.Privilege"></bean>
<bean id="security" class="cn.itcast.spring0909.aop.xml.salary.Security"></bean>
<bean id="salaryManager" class="cn.itcast.spring0909.aop.xml.salary.SalaryManager"></bean>
<!--
一个切入点表达式可以配置很多个切面
还可以配置很多个切入点表达式
-->
<aop:config>
<aop:pointcut expression="execution(* cn.itcast.spring0909.aop.xml.salary.SalaryManager.*(..))" id="perform"/>
<aop:aspect ref="logger">
<aop:before method="logging" pointcut-ref="perform"/>
</aop:aspect>
<aop:aspect ref="security">
<aop:before method="security" pointcut-ref="perform"/>
</aop:aspect>
<aop:aspect ref="privilege">
<aop:before method="privilege" pointcut-ref="perform"/>
</aop:aspect>
</aop:config>
</beans>
public class SalaryTest extends SpringHelper{
static{
path = "cn/itcast/spring0909/aop/xml/salary/applicationContext.xml";
}
@Test
public void test(){
SalaryManager salaryManager = (SalaryManager)context.getBean("salaryManager");
salaryManager.showSalary();
}
}