五个通知
1)前置通知 :函数执行前增强
2)后置通知 :函数执行后增强,除非异常,最后执行
3)环绕通知 :函数执行的前后都增强
4)异常通知 :出现异常的时候执行
5)最终通知:不管出不出现异常,都会执行,类似于异常捕获
的finally
五个通知完全基于注解开发
- 主类编写:
package Dao;
import org.springframework.stereotype.Component;
@Component//注解 创建对象
public class UserLogin {
public void login(){
System.out.println("now is logining......");
}
}
- 代理类编写:
package Dao;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.junit.jupiter.api.Order;
import org.springframework.stereotype.Component;
@Component//创建对象
@Aspect//切面 生成代理对象
public class UserLogin_Proxy {
@Before(value = "execution(* Dao.UserLogin.login())")
public void before(){
System.out.println("在login前执行.....【前置通知】");
}
@After(value = "execution(* Dao.UserLogin.login())")
public void after(){
System.out.println("在login后执行.....但还没有返回返回值...【最终通知】");
}
@AfterReturning(value = "execution(* Dao.UserLogin.login())")
public void afterReturning(){
System.out.println("在login后执行.........在返回值之后(最后执行)...【后置通知(返回通知)】");
}
@Around(value = "execution(* Dao.UserLogin.login())")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("在login前执行........【环绕通知】");
//被增强的方法执行 login
proceedingJoinPoint.proceed();
System.out.println("在login后执行........【环绕通知】");
}
@AfterThrowing(value = "execution(* Dao.UserLogin.login())")
public void afterThrowing(){
System.out.println("在login产生异常时执行........【异常通知】");
}
}
- 配置类编写:
package Config_replace_xml;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration//作为配置类,代替xml文件
@ComponentScan(basePackages = {"Dao"})
@EnableAspectJAutoProxy(proxyTargetClass = true)//开启Aspect生成代理对象
public class Config_class {
}
- 测试类编写:
package TestPackage;
import Config_replace_xml.Config_class;
import Dao.UserLogin;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestDemo2 {
@Test
public void Testdemo2(){
ApplicationContext context =
new AnnotationConfigApplicationContext(Config_class.class);
UserLogin userLogin = context.getBean("userLogin", UserLogin.class);
System.out.println(userLogin);
userLogin.login();
}
}
运行结果
- 文件排布为:
配置文件基于xml编写(与上面结果等价)
- 只需要删除配置类
Config_class
,再添加xml配置文件
即可 - xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!--命名空间设定 context aop -->
<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"
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">
<!--开启注解扫描-->
<context:component-scan base-package="Dao"></context:component-scan>
<!--开启代理对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
- 测试类改写为:
package TestPackage;
import Config_replace_xml.Config_class;
import Dao.UserLogin;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestDemo2 {
@Test
public void Testdemo2(){
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml");
UserLogin userLogin = context.getBean("userLogin", UserLogin.class);
System.out.println(userLogin);
userLogin.login();
}
}
测试结果等价