spring中的事件处理

如果一个 bean 实现 ApplicationListener,那么每次 ApplicationEvent 被发布到 ApplicationContext 上,那个 bean 会被通知。

标准事件:

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
标准事件 激活时机
ContextRefreshedEvent ApplicationContext 被初始化或刷新时,或调用ConfigurableApplicationContext接口的refresh()
ContextStartedEvent 调用ConfigurableApplicationContext接口的start()时
ContextStoppedEvent 调用ConfigurableApplicationContext接口的stop()时
ContextClosedEvent 调用ConfigurableApplicationContext接口的close()时
RequestHandledEvent 暂无

 

 

 

 

 

Spring 的事件处理是单线程的

 

监听上下文标准事件:

  • 创建实现ApplicationListener接口的事件处理类,并在接口方法onApplicationEvent()中实现接收到事件的逻辑
  • 将事件处理类声明为bean
  • 事件处理类无需其他类继承,当applicationContext发生变化时事件自动激活。

 spring自定义事件

  • class CustomEvent extends ApplicationEvent
  • class CustomEventPublisher implements ApplicationEventPublisherAware
  • class CustomEventHandler implements ApplicationListener<CustomEvent>
  • 在beans.xml中将CustomEventPublisher ,CustomEventHandler声明为bean
  • 当调用ApplicationEventPublisher的publishEvent(CustomEvent)时,自定义事件被激活
 1 // CustomEvent.java
 2 public class CustomEvent extends ApplicationEvent{
 3 
 4     public CustomEvent(Object source) {
 5         super(source);
 6     }
 7     
 8     public String toString() {
 9         return "My Custom Event";
10     }
11 
12 }
13 
14 // CustomEventHandler .java
15 public class CustomEventHandler implements ApplicationListener<CustomEvent> {
16 
17     @Override
18     public void onApplicationEvent(CustomEvent arg0) {
19         System.err.println(arg0.toString());
20     }
21     
22 }
23 
24 // CustomEventPublisher.java
25 public class CustomEventPublisher implements ApplicationEventPublisherAware{
26     private ApplicationEventPublisher publisher; 27 
28     @Override
29     public void setApplicationEventPublisher(ApplicationEventPublisher arg0) {
30         this.publisher = arg0;
31     }
32     
33     public void publish() {
34         CustomEvent ce = new CustomEvent(this);
35  publisher.publishEvent(ce);
36     }
37 
38 }
39 
40 // MainApp.java
41 public class MainApp {
42     public static void main(String[] args) {
43         ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
44         CustomEventPublisher publisher = (CustomEventPublisher) context.getBean("customEventPublisher");
45         publisher.publish();
46         publisher.publish();
47     }
48 }
49 
50 // beans.xml
51 <bean id="customEventPublisher" class="com.tutorialspoint.CustomEventPublisher"></bean>
52 <bean id="CustomEventHandler" class="com.tutorialspoint.CustomEventHandler"></bean>

spring框架的AOP

通知 描述
前置通知 在一个方法执行之前,执行通知。
后置通知 在一个方法执行之后,不考虑其结果,执行通知。
返回后通知 在一个方法执行之后,只有在方法成功完成时,才能执行通知。
抛出异常后通知 在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。
环绕通知 在建议方法调用之前和之后,执行通知。

1. spring中基于AOP的xml架构

重点是beans.xml文件

  • <aop:config>标签
  • <aop:aspect id="" ref="某个bean-id">
  • <aop:pointcut expression="execution(* com.tutorialspoint.*.*(..))" id="pointcut-id">
  • <aop:before method="" pointcut-ref="pointcut-id">
  • <aop:after method="" pointcut-ref="pointcut-id">
  • <aop:after-returning method="" pointcut-ref="pointcut-id" returning="">
  • <aop:after-throwing method="" pointcut-ref="pointcut-id" throwing="" >

returning与throwing要指定method中返回的对象,拼写要一致

  1 // beans.xml
  2 <?xml version="1.0" encoding="UTF-8"?>
  3 <beans
  4     xmlns="http://www.springframework.org/schema/beans"
  5     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  6     xmlns:aop="http://www.springframework.org/schema/aop"
  7     xsi:schemaLocation="http://www.springframework.org/schema/beans
  8     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
  9     http://www.springframework.org/schema/aop 
 10     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
 11     
 12     <aop:config>
 13         <aop:aspect id="log" ref="logging">
 14             <aop:pointcut expression="execution(* com.tutorialspoint.*.*(..))" id="selectAll"/>
 15             <aop:before method="beforeAdvice" pointcut-ref="selectAll"/>
 16             <aop:after method="afterAdvice" pointcut-ref="selectAll"/>
 17             <aop:after-returning 
 18                 method="afterReturningAdvice" 
 19                 returning="retVal"
 20                 pointcut-ref="selectAll"/>
 21             <aop:after-throwing 
 22                 method="afterThrowingAdvice"
 23                 throwing="excep"
 24                 pointcut-ref="selectAll"/>
 25         </aop:aspect>
 26     </aop:config>
 27     
 28     <bean id="student" class="com.tutorialspoint.Student">
 29         <property name="name" value="Zara"/>
 30         <property name="age" value="11"/>
 31     </bean>
 32     
 33     <bean id="course" class="com.tutorialspoint.Course">
 34         <property name="courseName" value="English"/>
 35         <property name="courseId" value="12"/>
 36     </bean>
 37     
 38     <bean id="logging" class="com.tutorialspoint.Logging"/>
 39 
 40 </beans>
 41 
 42 // Logging.java
 43 public class Logging {
 44     public void beforeAdvice() {
 45         System.out.println("Going to setup student profile.");
 46     }
 47     public void afterAdvice() {
 48         System.out.println("Student profile has been setup.");
 49     }
 50     public void afterReturningAdvice(Object retVal) {
 51         System.out.println("Returning:"+retVal.toString());
 52     }
 53     public void afterThrowingAdvice(IllegalArgumentException excep) {
 54         System.out.println("There has been an exception: "+excep.toString());
 55     }
 56     
 57 }
 58 
 59 // Student.java
 60 public class Student {
 61     private Integer age;
 62     private String name;
 63     public Integer getAge() {
 64         System.out.println("Studetn getAge()   Age : " + age );
 65         return age;
 66     }
 67     public void setAge(Integer age) {
 68         this.age = age;
 69     }
 70     public String getName() {
 71         System.out.println("Student getName()  Name : " + name );
 72         return name;
 73     }
 74     public void setName(String name) {
 75         this.name = name;
 76     }
 77     public void printThrowException() {
 78         System.out.println("Student printThrowException()   Exception raised");
 79         throw new IllegalArgumentException();
 80     }
 81 }
 82 
 83 // Course.java
 84 public class Course {
 85     String courseName;
 86     int courseId;
 87     public String getCourseName() {
 88         System.out.println("Course getCouseName() "+courseName);
 89         return courseName;
 90     }
 91     public void setCourseName(String courseName) {
 92         System.out.println("Course setCourseName() "+courseName);
 93         this.courseName = courseName;
 94     }
 95     public int getCourseId() {
 96         System.out.println("Couse getCourseId() "+courseId);
 97         return courseId;
 98     }
 99     public void setCourseId(int courseId) {
100         System.out.println("Course setCouseId() "+courseId);
101         this.courseId = courseId;
102     }
103 }
104 
105 //MainApp.java
106 public class MainApp {
107     public static void main(String[] args) {
108         ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
109         Student student = (Student) context.getBean("student");
110         student.getName();
111         student.getAge();
112         
113         Course course = (Course) context.getBean("course");
114         course.getCourseName();
115         course.getCourseId();
116         course.setCourseName("math"); 会报空指针异常 117         course.setCourseId(15); 118         
119         student.printThrowException();
120     }
121 }
运行结果:

Course setCourseName() English
Course setCouseId() 12
Going to setup student profile.
Student getName() Name : Zara
Student profile has been setup.
Returning:Zara
Going to setup student profile.
Studetn getAge() Age : 11
Student profile has been setup.
Returning:11
Going to setup student profile.
Course getCouseName() English
Student profile has been setup.
Returning:English
Going to setup student profile.
Couse getCourseId() 12
Student profile has been setup.
Returning:12
Going to setup student profile.
Course setCouseId() 15
Student profile has been setup.
Exception in thread "main" java.lang.NullPointerException

其中的Logging类定义了<aop:advice>的method

<aop:pointcut expression="execution(* com.tutorialspoint.*.*(..))"作用于beans.xml中下student bean之外的bean的所有方法,即student bean和coursebean
也可以指定
expression="execution(* com.tutorialspoint.Student.getName(..))"只作用于Student类下的getName()

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄