学习CDI的produces动态注入需要了解CDI的Inject注入和Alternative注入机制。
相关知识可以参见本人前面的博客。
alternative实现了部署时的组件解藕,produces实现了运行时的组件解藕。
其实本人对于produces的”动态注入”理解的也不是很深刻。
可以这样理解:
CDI的@Qualifier和@Alternative注解强调的是注入不同的组件,本质上是注入一个实现类的对象,而@Produces强调的是在不同的情景下注入不同的方法,从而实现”动态注入”的目的。
2.2.1 注入方式不同
a.普通注入:
注入组件的声明类:
package cn.edu.sdut.softlab;
@First //注意此处是在类的前面声明
public class FirstGreentingImpl implements Greeting {
public String greet(String name) {
System.out.println("欢迎: " + name);
return "First Greeting Implement:hello " + name;
}
}
b.Prooduces注入:
package cn.edu.sdut.softlab.connectionfactory;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import cn.edu.sdut.softlab.connectioninterface.Connection;
import cn.edu.sdut.softlab.connectioninterface.ConnectionImpl;
import cn.edu.sdut.sotflab.qualifier.MyConnection;
public class ConnectionFactory {
@Produces // 此处是在方法上进行声明,而且一个类中可以声明多个
@RequestScoped
@MyConnection
public Connection getConnection() {
System.out.println("ConnectionFactory.egtConnection is called ...");
Connection connectionFactory = new ConnectionImpl();
connectionFactory.connect();
return connectionFactory;
}
}
2.2.2 本质不同
看下面的组件声明类:
public class Resources {
// Expose an entity manager using the resource producer pattern
@SuppressWarnings("unused")
@PersistenceContext
@Produces
private EntityManager em;
@Produces
Logger getLogger(InjectionPoint ip) {
//注意此处创建或者说是引入了新的对象,这样Logger对象就可以在不同的 情景下得以调用,即动态注入,不用每次都要重新创建Logger对象了
String category = ip.getMember().getDeclaringClass().getName();
return Logger.getLogger(category);
}
@Produces
@RequestScoped
FacesContext getFacesContextInstance() {
//同上
return FacesContext.getCurrentInstance();
}
}
package cn.edu.sdut.softlab.connectionfactory;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import cn.edu.sdut.softlab.connectioninterface.Connection;
import cn.edu.sdut.softlab.connectioninterface.ConnectionImpl;
import cn.edu.sdut.sotflab.qualifier.MyConnection;
public class ConnectionFactory {
@Produces
@RequestScoped //周期声明
@MyConnection //自定义qualifier
public Connection getConnection() {
System.out.println(“ConnectionFactory.egtConnection is called …”);
Connection connectionFactory = new ConnectionImpl();
connectionFactory.connect();
return connectionFactory;
}
}
3.2 自定义qualifier
package cn.edu.sdut.sotflab.qualifier;
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 java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
*
* @author
*/
@Qualifier
@Target({ TYPE, METHOD, FIELD, PARAMETER })
@Retention(RUNTIME)
public @interface MyConnection {
}
接口:
package cn.edu.sdut.softlab.connectioninterface;
public interface Connection {
void connect();
void closeConnection();
String doSomething();
}
实现类:
package cn.edu.sdut.softlab.connectioninterface;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import cn.edu.sdut.sotflab.qualifier.Simple;
@Simple
public class ConnectionImpl implements Connection {
@PostConstruct
private void initConn() {
System.out.println("initConn is called...");
connect();
}
@PreDestroy
private void destroyConn() {
System.out.println("destroyConn is called...");
}
public void connect() {
System.out.println("Connecting...");
}
public void closeConnection() {
System.out.println("Closing connection...");
}
public String doSomething() {
String msg = "do somethinig...";
System.out.println(msg);
return msg;
}
}
Produces组件生成:
package cn.edu.sdut.softlab.connectionfactory;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import cn.edu.sdut.softlab.connectioninterface.Connection;
import cn.edu.sdut.softlab.connectioninterface.ConnectionImpl;
import cn.edu.sdut.sotflab.qualifier.MyConnection;
public class ConnectionFactory {
@Produces
@RequestScoped
@MyConnection
public Connection getConnection() {
System.out.println("ConnectionFactory.egtConnection is called ...");
Connection connectionFactory = new ConnectionImpl();
connectionFactory.connect();
return connectionFactory;
}
}
自定义Qualifier:
package cn.edu.sdut.sotflab.qualifier;
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 java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
*
* @author
*/
@Qualifier
@Target({ TYPE, METHOD, FIELD, PARAMETER })
@Retention(RUNTIME)
public @interface MyConnection {
}
组件注入(重要):
package cn.edu.sdut.softlab.controller;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import cn.edu.sdut.softlab.connectioninterface.Connection;
import cn.edu.sdut.sotflab.qualifier.MyConnection;
import cn.edu.sdut.sotflab.qualifier.Simple;
@Named("controller")
@RequestScoped
public class ConnectionController {
@Inject
@MyConnection
Connection connection;
public Connection getConnection() {
return connection;
}
public String doSomething() {
//connection.connect();
String connectMsg = "Connection has connnected!";
System.out.println(connectMsg);
return connectMsg;
}
}
使用命令:
mvn clean package wildfly:deploy
详细完整实例代码请移步:
https://github.com/GaoZiqiang/CDI-Alternative
--------------------- 本文来自 高自强 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_33429968/article/details/63251652?utm_source=copy