feat(springDemo): 添加 Server-Sent Events (SSE) 功能和代理演示
- 新增 SSEEmitter 类实现 Server-Sent Events功能 - 添加 ProxyDemo 类演示动态代理 - 更新 UserService 类,增加 Bean 生命周期相关注释 - 调整 application.yaml 文件格式
This commit is contained in:
parent
72843c9027
commit
25f4784daa
46
ForJdk8/src/main/java/cn/whaifree/tech/proxy/ProxyDemo.java
Normal file
46
ForJdk8/src/main/java/cn/whaifree/tech/proxy/ProxyDemo.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package cn.whaifree.tech.proxy;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/22 23:13
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class ProxyDemo {
|
||||||
|
|
||||||
|
interface base{
|
||||||
|
void print();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class A implements base {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void print() {
|
||||||
|
System.out.println("A");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
base a = (base)
|
||||||
|
java.lang.reflect.Proxy.newProxyInstance(
|
||||||
|
base.class.getClassLoader(),
|
||||||
|
new Class[]{
|
||||||
|
base.class
|
||||||
|
},
|
||||||
|
new InvocationHandler() {
|
||||||
|
@Override
|
||||||
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
|
System.out.println("ProxyA");
|
||||||
|
method.invoke(new A(), args);
|
||||||
|
System.out.println("after invoke");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
a.print();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package cn.whaifree.springdemo.controller.SSE;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/10/22 21:44
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class SSEEmitter {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int a = 127;
|
||||||
|
byte c = (byte) a;
|
||||||
|
System.out.println(Integer.toBinaryString(c));
|
||||||
|
System.out.println(c);
|
||||||
|
}
|
||||||
|
Map<String, SseEmitter> sseEmitterMap = new java.util.HashMap<>();
|
||||||
|
|
||||||
|
@GetMapping(value = "/sseStart", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||||
|
public SseEmitter sse(String key) {
|
||||||
|
System.out.println(key);
|
||||||
|
if (!sseEmitterMap.containsKey(key)) {
|
||||||
|
SseEmitter sseEmitter = new SseEmitter();
|
||||||
|
sseEmitterMap.put(key, sseEmitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sseEmitterMap.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("sendSSE")
|
||||||
|
public void send(String key, String message) {
|
||||||
|
if (sseEmitterMap.containsKey(key)) {
|
||||||
|
SseEmitter sseEmitter = sseEmitterMap.get(key);
|
||||||
|
try {
|
||||||
|
System.out.println(StrUtil.format("send message to {}:{}", key, message));
|
||||||
|
sseEmitter.send(message);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
throw new IllegalArgumentException("No such key");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,10 @@
|
|||||||
package cn.whaifree.springdemo.entity;
|
package cn.whaifree.springdemo.entity;
|
||||||
|
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import jakarta.annotation.PreDestroy;
|
import jakarta.annotation.PreDestroy;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.*;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.context.ApplicationContextAware;
|
||||||
@ -25,8 +23,50 @@ import org.springframework.core.annotation.Order;
|
|||||||
class Config {
|
class Config {
|
||||||
|
|
||||||
}
|
}
|
||||||
//@Component("userService")
|
|
||||||
public class UserService implements InitializingBean, DisposableBean, BeanFactoryAware, ApplicationContextAware, BeanPostProcessor,AutoCloseable {
|
/**
|
||||||
|
* <h1>Spring Bean生命周期</h1>
|
||||||
|
* <p>Spring Bean 的生命周期包括创建、初始化、使用、销毁等过程。</p>
|
||||||
|
* <p>Spring Bean 的生命周期</p>
|
||||||
|
*
|
||||||
|
* <li>实例化阶段:Bean 被实例化,Bean 实例化后,Bean 处于未初始化状态。</li>
|
||||||
|
* <li>初始化阶段:Bean 完成实例化后,Bean 处于初始化状态,Bean 实例变量可以被赋值。</li>
|
||||||
|
* <ul>
|
||||||
|
* <li><code>BeanNameAware.setBeanName</code></li>
|
||||||
|
* <li><code>BeanFactoryAware.setBeanFactory</code></li>
|
||||||
|
* <li><code>ApplicationContextAware.setApplicationContext</code></li>
|
||||||
|
* </ul>
|
||||||
|
* <ul>
|
||||||
|
* <li><code>@PostConstruct</code></li>
|
||||||
|
* <li><code>InitializingBean.afterPropertiesSet</code></li>
|
||||||
|
* <li><code>BeanPostProcessor.postProcessBeforeInitialization</code></li>
|
||||||
|
* <li>初始化</li>
|
||||||
|
* <li><code>BeanPostProcessor.postProcessAfterInitialization</code></li>
|
||||||
|
* </ul>
|
||||||
|
* <li>使用阶段:Bean 完成初始化后,Bean 处于可使用状态,Bean 可以被使用。</li>
|
||||||
|
* <li>销毁阶段:Bean 不再被使用时,Bean 处于销毁状态,Bean 实例将被销毁。</li>
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li><code>@PreDestroy</code></li>
|
||||||
|
* <li><code>DisposableBean.destroy</code></li>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* <h2>相关Aware注入:让 Bean 能够**感知**到它们所运行的环境或依赖的资源e</h2>
|
||||||
|
* <h2>为什么要叫Aware</h2>
|
||||||
|
* Aware是一个接口,
|
||||||
|
* 指示 Bean 有资格通过 Callback 样式方法由 Spring 容器通知特定框架对象。
|
||||||
|
* 实际的方法签名由各个子接口确定,但通常应仅包含一个接受单个参数的返回 void 的方法
|
||||||
|
*/
|
||||||
|
//@Component
|
||||||
|
public class UserService implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware, BeanPostProcessor, AutoCloseable {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行 BeanFactoryAware.setBeanFactory
|
* 执行 BeanFactoryAware.setBeanFactory
|
||||||
@ -43,14 +83,17 @@ public class UserService implements InitializingBean, DisposableBean, BeanFactor
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("cn.whaifree.springdemo.entity");
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("cn.whaifree.springdemo.entity");
|
||||||
UserService userService = context.getBean("userService", UserService.class);
|
UserService userService = context.getBean("userService", UserService.class);
|
||||||
|
System.out.println(userService);
|
||||||
// 执行 DisposableBean
|
// 执行 DisposableBean
|
||||||
|
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String beanName;
|
private String beanName;
|
||||||
private BeanFactory beanFactory;
|
private BeanFactory beanFactory;
|
||||||
private ApplicationContext applicationContext;
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||||
System.out.println("执行 BeanPostProcessor.postProcessBeforeInitialization");
|
System.out.println("执行 BeanPostProcessor.postProcessBeforeInitialization");
|
||||||
@ -73,18 +116,32 @@ public class UserService implements InitializingBean, DisposableBean, BeanFactor
|
|||||||
System.out.println("UserService destroy");
|
System.out.println("UserService destroy");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods(java.lang.String, java.lang.Object)
|
||||||
|
*
|
||||||
|
* if (bean instanceof BeanFactoryAware beanFactoryAware) { // 如果实现了BeanFactoryAware接口,就执行setBeanFactory
|
||||||
|
* beanFactoryAware.setBeanFactory(AbstractAutowireCapableBeanFactory.this);
|
||||||
|
* }
|
||||||
|
* @param beanFactory owning BeanFactory (never {@code null}).
|
||||||
|
* The bean can immediately call methods on the factory.
|
||||||
|
* @throws BeansException
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||||
this.beanFactory = beanFactory;
|
this.beanFactory = beanFactory;
|
||||||
System.out.println("执行 BeanFactoryAware.setBeanFactory");
|
System.out.println("执行 BeanFactoryAware.setBeanFactory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
System.out.println("执行 ApplicationContextAware.setApplicationContext");
|
System.out.println("ApplicationContextAware.setApplicationContext(ApplicationContext applicationContext) 可以获取applicantionContext,便于获取context,可以提取变成一个公共的component,每次从这个component获取Bean");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
System.out.println("执行 @PostConstruct");
|
System.out.println("执行 @PostConstruct");
|
||||||
@ -100,6 +157,12 @@ public class UserService implements InitializingBean, DisposableBean, BeanFactor
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBeanName(String name) {
|
||||||
|
System.out.println("执行 BeanNameAware.setBeanName");
|
||||||
|
// 修改原来的BeanName
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods(java.lang.String, java.lang.Object)
|
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods(java.lang.String, java.lang.Object)
|
||||||
@ -121,3 +184,18 @@ public class UserService implements InitializingBean, DisposableBean, BeanFactor
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模拟工具类,其实就是可以随时获取本Context
|
||||||
|
*/
|
||||||
|
//@Component
|
||||||
|
//class SpringContextUtil implements ApplicationContextAware {
|
||||||
|
// static ApplicationContext applicationContext;
|
||||||
|
// @Override
|
||||||
|
// public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
// this.applicationContext = applicationContext;
|
||||||
|
// }
|
||||||
|
// public static ApplicationContext getApplicationContext(){
|
||||||
|
// return applicationContext;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
@ -8,6 +8,7 @@ spring:
|
|||||||
|
|
||||||
data:
|
data:
|
||||||
redis:
|
redis:
|
||||||
|
|
||||||
host: localhost
|
host: localhost
|
||||||
port: 6379
|
port: 6379
|
||||||
# 选择db1
|
# 选择db1
|
||||||
|
Loading…
Reference in New Issue
Block a user