SpringIOC——内部工具——事件通讯机制
基于发布订阅的设计模式,我们想每个bean对象去订阅一些内容,当这些内容发过来的时候完成bean的一些处理,而不需要外部主动调取,是内部监听到了自动去做处理这些代码设计在spring中可以实现;
(1)先定义事件实体
/**
* 创建事件数据类型
* 用于定义和区分事件,以及传入事件的消息数据
*/
public class MyEvent extends ApplicationEvent {
public MyEvent(String message) {
super(message);
}
}
public class MyEventTwo extends ApplicationEvent {
public MyEventTwo(String message) {
super(message);
}
}
(2)在需要定义监听器的组件,写好方法注解,我这里演示就直接写个类,实际上只是是bean就行
/**
* 在任意一个bean组件中可以利用事件的方式去做一个监听,然后动态更新bean的值
* 一般监听机制就说这么传值去运用的
*/
@Component
public class MyEventListener {
String data="ssss";
/**
* 监听一个事件
* @param myevent
*/
@Order(1)
@EventListener(MyEvent.class)//可以监听多个
public void eventCallBack1(MyEvent myevent) {
String message=(String)myevent.getSource();
this.data=message;
System.out.println("收到自定义事件"+message);
}
/**
* 监听多个事件
*/
@Order(2)
@EventListener({MyEvent.class, MyEventTwo.class})
public void eventCallBack2(ApplicationEvent evnet) {
/**
* 根据事件类型做不同的业务处理
*/
if(evnet instanceof MyEvent){
String message=(String)evnet.getSource();
this.data=message;
System.out.println("收到自定义事件"+message);
}
if(evnet instanceof MyEventTwo){
String message=(String)evnet.getSource();
this.data=message;
System.out.println("收到自定义事件"+message);
}
}
}
(3)发布事件
@RestController
public class SpringIocTestController {
@Autowired
ApplicationEventPublisher applicationEventPublisher;
@PostMapping("/IocTestController/evnetListener")
public ResponseVO sendMessage(String message){
applicationEventPublisher.publishEvent(new MyEvent(message));
return ApiResult.success("成功");
}
}
(4)Spring中默认的事件
/**
* Spring中,在生命周期都定义了一系列的事件发布
* 通过这些事件我们可以拿到ioc中的一些核心数据
*/
@Configuration
public class DefalutEventListener {
// ContextRefreshedEvent 当容器被实例化或refreshed时发布.如调用refresh()方法, 此处的实例化是指所有的bean都已被加载,后置处理器都被激活,所有单例bean都已被实例化, 所有的容器对象都已准备好可使用. 如果容器支持热重载,则refresh可以被触发多次(XmlWebApplicatonContext支持热刷新,而GenericApplicationContext则不支持)
// ContextStartedEvent 当容器启动时发布,即调用start()方法, 已启用意味着所有的Lifecycle bean都已显式接收到了start信号
// ContextStoppedEvent 当容器停止时发布,即调用stop()方法, 即所有的Lifecycle bean都已显式接收到了stop信号 , 关闭的容器可以通过start()方法重启
// ContextClosedEvent 当容器关闭时发布,即调用close方法, 关闭意味着所有的单例bean都已被销毁.关闭的容器不能被重启或refresh
// RequestHandledEvent 这只在使用spring的DispatcherServlet时有效,当一个请求被处理完成时发布
@EventListener(ContextRefreshedEvent.class)
public void ContextRefreshedEvent(ContextRefreshedEvent evnet) {
AnnotationConfigServletWebApplicationContext source = (AnnotationConfigServletWebApplicationContext)evnet.getSource();
System.out.println(source);
}
}
SpringIOC——内部工具——反射工具类
以下工具类都是利用类执行数据的修改和方法的调用,这种编程方式称之为元编程
ReflectionUtils.findField(User.class,"username");//获取filed对象
ReflectionUtils.findMethod(User.class,"check");//获取method方法
ReflectionUtils.setField(user.getClass().getField("useranem"),user,"username")//更改某个对象的,filed值
ReflectionUtils.invokeMethod(user,"check");//执行某个对象的方法
SpringIOC——内部工具——注解工具类
AnnotationUtils.getAnnotation(ParentController.class, RequestMapping.class);
AnnotationUtils.findAnnotation(ParentController.class, RequestMapping.class);
AnnotatedElementUtils.isAnnotated(ParentController.class, RequestMapping.class);
AnnotatedElementUtils.getMergedAnnotation(ParentController.class, RequestMapping.class);
AnnotatedElementUtils.hasAnnotation(ParentController.class, RequestMapping.class);
AnnotatedElementUtils.findMergedAnnotation(ParentController.class, RequestMapping.class);
SpringIOC——内部工具——文件工具类
【Propeties工具】
Properties props = PropertiesLoaderUtils.loadAllProperties("jdbc.properties");// jdbc.properties 是位于类路径下的文件
String username = props.getProperty("username");
String password = props.getProperty("password");
【文件复制】
OutputStream os = new ByteArrayOutputStream(); // 将文件内容拷贝到一个输出流中。然后再用os写出去
FileCopyUtils.copy(res1.getInputStream(), os);
FileCopyUtils.copy(res1.getFile(),new File(res1.getFile().getParent() + "/file2.txt")); // 将文件内容拷贝到另一个目标文件
FileCopyUtils.copyToByteArray(res1.getFile());//将文件内容拷贝到一个 byte[] 中 byte[] fileData
FileCopyUtils.copyToString(new FileReader(res1.getFile()));// 将文件内容拷贝到一个 String String fileStr
【获取文件】
File clsFile = ResourceUtils.getFile("classpath:conf/file1.txt");
File httpFile = ResourceUtils.getFile("file:D:/masterSpring/chapter23/src/conf/file1.txt";
Resource res1 = new FileSystemResource("D:/masterSpring/chapter23/webapp/WEB-INF/classes/conf/file1.txt");// 使用系统文件路径方式加载文件
Resource res2 = new ClassPathResource("conf/file1.txt");//使用类路径方式加载文件
EncodedResource encRes = new EncodedResource(res, "UTF-8");