如果一个 bean 实现 ApplicationListener,那么每次 ApplicationEvent 被发布到 ApplicationContext 上,那个 bean 会被通知。
标准事件:
标准事件 | 激活时机 |
ContextRefreshedEvent | ApplicationContext 被初始化或刷新时,或调用ConfigurableApplicationContext接口的refresh() |
ContextStartedEvent | 调用ConfigurableApplicationContext接口的start()时 |
ContextStoppedEvent | 调用ConfigurableApplicationContext接口的stop()时 |
ContextClosedEvent | 调用ConfigurableApplicationContext接口的close()时 |
RequestHandledEvent | 暂无 |
Spring 的事件处理是单线程的
监听上下文标准事件:
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>
通知 | 描述 |
---|---|
前置通知 | 在一个方法执行之前,执行通知。 |
后置通知 | 在一个方法执行之后,不考虑其结果,执行通知。 |
返回后通知 | 在一个方法执行之后,只有在方法成功完成时,才能执行通知。 |
抛出异常后通知 | 在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。 |
环绕通知 | 在建议方法调用之前和之后,执行通知。 |
重点是beans.xml文件
returning与throwing要指定method中返回的对象,拼写要一致
// beans.xml <?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <aop:config> <aop:aspect id="log" ref="logging"> <aop:pointcut expression="execution(* com.tutorialspoint.*.*(..))" id="selectAll"/> <aop:before method="beforeAdvice" pointcut-ref="selectAll"/> <aop:after method="afterAdvice" pointcut-ref="selectAll"/> <aop:after-returning method="afterReturningAdvice" returning="retVal" pointcut-ref="selectAll"/> <aop:after-throwing method="afterThrowingAdvice" throwing="excep" pointcut-ref="selectAll"/> </aop:aspect> </aop:config> <bean id="student" class="com.tutorialspoint.Student"> <property name="name" value="Zara"/> <property name="age" value="11"/> </bean> <bean id="course" class="com.tutorialspoint.Course"> <property name="courseName" value="English"/> <property name="courseId" value="12"/> </bean> <bean id="logging" class="com.tutorialspoint.Logging"/> </beans> // Logging.java public class Logging { public void beforeAdvice() { System.out.println("Going to setup student profile."); } public void afterAdvice() { System.out.println("Student profile has been setup."); } public void afterReturningAdvice(Object retVal) { System.out.println("Returning:"+retVal.toString()); } public void afterThrowingAdvice(IllegalArgumentException excep) { System.out.println("There has been an exception: "+excep.toString()); } } // Student.java public class Student { private Integer age; private String name; public Integer getAge() { System.out.println("Studetn getAge() Age : " + age ); return age; } public void setAge(Integer age) { this.age = age; } public String getName() { System.out.println("Student getName() Name : " + name ); return name; } public void setName(String name) { this.name = name; } public void printThrowException() { System.out.println("Student printThrowException() Exception raised"); throw new IllegalArgumentException(); } } // Couse.java public class Course { String courseName; int courseId; public String getCourseName() { System.out.println("Course getCouseName() "+courseName); return courseName; } public void setCourseName(String courseName) { this.courseName = courseName; } public int getCourseId() { System.out.println("Couse getCourseId() "+courseId); return courseId; } public void setCourseId(int courseId) { this.courseId = courseId; } } // MainApp.java public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Student student = (Student) context.getBean("student"); student.getName(); student.getAge(); Course course = (Course) context.getBean("course"); course.getCourseName(); course.getCourseId(); student.printThrowException(); } }
运行结果: 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. Student printThrowException() Exception raised Student profile has been setup. There has been an exception: java.lang.IllegalArgumentException
其中的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()
原文:https://www.cnblogs.com/yfs123456/p/10667885.html