环境搭建
和xml方式需要导入的包一致,xml方式中的约束是全部约束了,所以这次导入那个就行。
配置
和注解IOC一样,也需要在配置文件中配置信息,让Spring知道AOP使用注解方式进行。
<!-- 打开注解方式的AOP -->
<aop:aspectj-autoproxy />
入门
使用@Aspect
、@Before
、@AfterReturning
、@Around
注解
<?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"
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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 打开注解方式的AOP -->
<aop:aspectj-autoproxy />
<bean id="userDao" class="com.spring.annotation.UserDaoImpl"></bean>
<bean id="myAspectJ" class="com.spring.annotation.MyAspectJ"></bean>
</beans>
public class UserDaoImpl implements UserDao {
public void delete() {
System.out.println("简简单单的删除");
}
public Integer delete(String userId, Double type) {
System.out.println("delete : " + userId);
System.out.println("delete : " + type);
return 100;
}
public Boolean delete(Double type, String userId) {
System.out.println("delete : " + userId + " " + type);
return true;
}
}
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
public class MyAspectJ {
/**
* 前置增强,value表达式和xml方式一致
*/
@Before(value="execution(void com.spring.annotation.UserDaoImpl.delete())")
public void before() {
System.out.println("before");
}
/**
* 后置增强,value表达式和xml方式一致
*/
@AfterReturning(value="execution(Boolean com.spring.annotation.UserDaoImpl.delete(java.lang.Double, java.lang.String))",
returning="ret")
public void after(Boolean ret) {
System.out.println(ret);
System.out.println("after");
}
@Around(value="execution(Integer com.spring.annotation.UserDaoImpl.delete(java.lang.String, java.lang.Double))")
public Integer around(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();
for(Object o : args)
System.out.println(o);
//执行切点
Integer proceed = (Integer)pjp.proceed();
return proceed;
}
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao ud = (UserDao)ac.getBean("userDao");
Integer delete = ud.delete("HelloWorld", 11.0);
System.out.println(delete);
}
}
切入点注解
在上面的代码中,把注解加在通知的上面,类似于xml方式的
<aop:aspect ref="myAspectJ">
<aop:around method="around" pointcut-ref="cut1" />
</aop:aspect>
但是这样的话后期修改很麻烦,所以使用注解完成类似于下面,可以通过id添加通知的操作。
<aop:pointcut expression="execution(Integer com.spring.aopxml.UserDaoImpl.delete(..))" id="cut1"/>
@Around(value="MyAspectJ.cut1")
public Integer around(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();
for(Object o : args)
System.out.println(o);
//执行切点
Integer proceed = (Integer)pjp.proceed();
return proceed;
}
/*
* 不能使用属性
*/
@Pointcut(value="execution(Integer com.spring.annotation.UserDaoImpl.delete(java.lang.String, java.lang.Double))")
private void cut1() {}