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;
|
||||
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.*;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@ -22,11 +20,53 @@ import org.springframework.core.annotation.Order;
|
||||
*/
|
||||
@Configuration
|
||||
@Order(-1)
|
||||
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
|
||||
@ -43,14 +83,17 @@ public class UserService implements InitializingBean, DisposableBean, BeanFactor
|
||||
public static void main(String[] args) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("cn.whaifree.springdemo.entity");
|
||||
UserService userService = context.getBean("userService", UserService.class);
|
||||
System.out.println(userService);
|
||||
// 执行 DisposableBean
|
||||
|
||||
context.close();
|
||||
}
|
||||
|
||||
private String beanName;
|
||||
private BeanFactory beanFactory;
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
System.out.println("执行 BeanPostProcessor.postProcessBeforeInitialization");
|
||||
@ -73,25 +116,39 @@ public class UserService implements InitializingBean, DisposableBean, BeanFactor
|
||||
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
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
System.out.println("执行 BeanFactoryAware.setBeanFactory");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
System.out.println("执行 ApplicationContextAware.setApplicationContext");
|
||||
System.out.println("ApplicationContextAware.setApplicationContext(ApplicationContext applicationContext) 可以获取applicantionContext,便于获取context,可以提取变成一个公共的component,每次从这个component获取Bean");
|
||||
}
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void init(){
|
||||
public void init() {
|
||||
System.out.println("执行 @PostConstruct");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void destroyMethod(){
|
||||
public void destroyMethod() {
|
||||
System.out.println("执行 @PreDestroy");
|
||||
}
|
||||
|
||||
@ -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)
|
||||
@ -107,7 +170,7 @@ public class UserService implements InitializingBean, DisposableBean, BeanFactor
|
||||
* if (bean instanceof Aware) {
|
||||
* if (bean instanceof BeanNameAware beanNameAware) {
|
||||
* beanNameAware.setBeanName(beanName);
|
||||
* }
|
||||
* }
|
||||
* if (bean instanceof BeanClassLoaderAware beanClassLoaderAware) {
|
||||
* ClassLoader bcl = getBeanClassLoader();
|
||||
* if (bcl != null) {
|
||||
@ -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:
|
||||
redis:
|
||||
|
||||
host: localhost
|
||||
port: 6379
|
||||
# 选择db1
|
||||
|
Loading…
Reference in New Issue
Block a user