AOP的基本概念:面向切面编程,作用类似于反射代理。在目标方法执行前后可自动的执行其他代码(称为增强)。其他代码又被称为切面。我们要关注的是如何写其他代码而不是如何调用其他代码。因此称之为面向切面编程。
AOP编程的主要步骤
public interface EmailDao {
public void send();
public void receive();
}
接口的实现类:
@Component//对象的创建交给容器来管理
public class EmailDaoImpl implements EmailDao {
@Override public void send() {
System.out.println("发送邮件");
}
@Override public void receive() {
System.out.println("收到邮件");
}
}
定义切面:@Aspect表示这是一个切面类,切面类也是交给spring容器来管理的。用execution语句来指定增强点。可以在一个空方法上用@Pointcut来指定增强点,之后可以用方法名加扩号来取代execution语句。如下面代码中第三个方法上面。但是早期的一些版本也不支持。
execution语句解释:execution(* com.AOP.EmailDao.se*(…)),第一个*表示访问权限为任意;后面的路径表示该路径下的以se开头的方法,不写se表示任意方法,参数任意。
@Aspect
@Component
public class MyService {
@Pointcut("execution(* com.AOP.EmailDao.re*(..))")
public void point(){}
@Before("execution(* com.AOP.EmailDao.se*(..))")//目标方法执行之前执行下面的代码
public void send()
{
System.out.println("发送邮件之前");
}
@After("point()")//也可以写成@After("execution(* com.AOP.EmailDao.re*(..))"),表示该结构下的以re开头的方法执行完后都会执行以下方法。
public void receive()
{
System.out.println("接受邮件之后");
}
}
因为是基于注解,所有没有ApplicatioonContext.xml文件,要通过java类来配置:
@Configurable
@EnableAspectJAutoProxy//开启代理,一定要加
public class MyConfig {
@Bean("email")
public EmailDao getEmailDao()
{
return new EmailDaoImpl();
}
@Bean
public AllService getAllService()
{
return new AllService();
}
}
main方法:
public class Main {
public static void main(String[] args) {
ApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class);
EmailDao email=(EmailDao)context.getBean("email");
email.send();
email.receive();
}
}
运行结果:
发送邮件之前
发送邮件
收到邮件
接受邮件之后
验证能否对普通类中的方法进行增强,将切点的位置移动到一个普通类的一个普通方法(不是继承来的)。对该方法进行增强。
@Component
public class test {
public void show()//要增强的方法
{
System.out.println("Hello world");
}
}
切面类中:
@Before("execution(* com.AOP.test.*(..))")
public void beforeNormalMethod()
{
System.out.println("hi............");
}
配置类中:
@Bean
public test getTest()
{
return new test();
}
main方法中:
test t=context.getBean(test.class);
t.show();
运行结果:
hi............
Hello world
有返回值后进行增强:
切面类:
@AfterReturning(value = "execution(* com.AOP.test.*(..))",returning = "retVal")
public void afterReturnMethod(Object retVal)
{
System.out.println("有返回值"+((Integer)retVal+666));//对返回值加666后进行输出
}
被切点命中的方法:
public int show()
{
return 0;
}
运行结果:
有返回值666
方法抛出异常时进行增强:
@AfterThrowing(value = "execution(* com.AOP.test.*(..))",throwing = "exc")
public void afterThrowingMethod(Exception exc)
{
System.out.println("有异常了-----"+exc);
}
被命中的方法:
public int show()
{
return 10/0;//会抛出异常
}
运行结果:
有异常了-----java.lang.ArithmeticException: / by zero
方法周围执行增强方法,相当于反射代理:
@Around("execution(* com.AOP.test.*(..))")
public void aroundMethod(ProceedingJoinPoint proceedingJoinPoint)throws Throwable
{
System.out.println("执行目标方法之前");
proceedingJoinPoint.proceed();//执行目标方法
System.out.println("执行目标方法之后");
}
public void show()
{
System.out.println("this is show method");
}
运行结果:
执行目标方法之前
this is show method
执行目标方法之后
上一篇 |
---The End---
|
下一篇 |