[笔记] @Produces 和 @Inject、@Bean 和 @Autowired
@Inject 注解的变量会自动调用构造函数初始化
如果希望不止是调用默认构造函数,可以使用 @Produces 动态生成
先定义一个 MyConnection 这是我们要用 @Inject 注解的变量的类型
package com.example.demo.entity;
import com.example.demo.utils.Logger;
public class MyConnection {
private final String host;
private final String port;
public MyConnection(String host, String port) {
this.host = host;
this.port = port;
}
public void connect() {
Logger.message("Connect to " + this.host + ":" + this.port);
}
public void query() {
Logger.message("execute query");
}
public void disconnect() {
Logger.message("Disconnect " + this.host + ":" + this.port);
}
}
定义一个注解,用于 @Inject 的时候可以传参数
package com.example.demo.annotation;
import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Qualifier
@Target({TYPE, METHOD, FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface MyProducedConnection {
String host() default "";
String port() default "";
}
定义一个 Factory,这里 @Produces 注解的函数会和 @Inject 配合,由 @Inject 注解的变量,如果变量类型是 MyConnection,就会找到这个由 @Produces 注解的,返回类型为 MyConnection 的函数
@RequestScoped 不是必须的,它表示这个函数产生的变量是 RequestScoped 的
@MyProducedConnection 也不是必须的,@Inject 再加这个注解,可用于传参数给 produces 函数
@Disposes 注解的函数,会在 @Inject 注解的变量失效的时候被调用
package com.example.demo.factory;
import com.example.demo.annotation.MyProducedConnection;
import com.example.demo.entity.MyConnection;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
@Dependent
public class MyConnectionFactory {
@Produces
@MyProducedConnection
@RequestScoped
public MyConnection produce(InjectionPoint injectionPoint) {
MyProducedConnection annotation =
injectionPoint.getAnnotated().getAnnotation(MyProducedConnection.class);
String host = annotation.host();
String port = annotation.port();
MyConnection conn = new MyConnection(host, port);
conn.connect();
return conn;
}
public void closeConn(@Disposes @MyProducedConnection MyConnection conn) {
conn.disconnect();
}
}
应用,通过 @Inject + @MyProducedConnection 由 produce 函数创建了变量
每定义一个变量,会执行一次 produce 函数
@ApplicationScoped
@Named
public class DemoService {
@Inject
@MyProducedConnection(host = "192.168.1.1", port = "8192")
private MyConnection myConnection;
@PostConstruct
public void init() {
myConnection.query();
}
}
SpringBoot 环境下没起作用
SpringBoot 环境下可以使用 @Bean 和 @Autowired
@Bean
@Scope(SCOPE_REQUEST)
public MyConnection produce() {
Logger.message("MyConnectionFactory produce conn");
MyConnection conn = new MyConnection("192.168.1.1", "8912");
conn.connect();
return conn;
}
@Bean 函数一定会被执行,不管有没有定义 @Autowired MyConnection
应用,@Autowired 注解的 MyConnection 变量,会直接使用 @Bean 创建的实例,不会重新调用 produce,如果定义多个 @Autowired MyConnection 变量,实际上都是指向同一个,并不会重新调用 produce
@Autowired
private MyConnection myConnection;
但可以通过 name 属性实现多个 @Bean 和多个变量
@Bean(name = "test1")
public MyConnection produce1() {
Logger.message("MyConnectionFactory produce conn");
MyConnection conn = new MyConnection("192.168.1.1", "8912");
conn.connect();
return conn;
}
@Bean(name = "test2")
public MyConnection produce2() {
Logger.message("MyConnectionFactory produce conn");
MyConnection conn = new MyConnection("192.168.1.2", "8912");
conn.connect();
return conn;
}
应用
@Resource(name = "test1")
private MyConnection myConnection1;
@Resource(name = "test2")
private MyConnection myConnection2;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界