CDI系列学习--produces动态注入注解的使用和讲解

1 知识储备

学习CDI的produces动态注入需要了解CDI的Inject注入和Alternative注入机制。
相关知识可以参见本人前面的博客。

2 produces概念讲解

alternative实现了部署时的组件解藕,produces实现了运行时的组件解藕。

2.1 关于produces动态注入的理解

其实本人对于produces的"动态注入"理解的也不是很深刻。
个人认为可以这样理解:

CDI的@Qualifier和@Alternative注解强调的是注入不同的组件,本质上是注入一个实现类的对象,而@Produces强调的是在不同的情景下注入不同的方法,从而实现"动态注入"的目的。

2.2 辨析

2.2.1 注入方式不同

1.普通注入
注入组件的声明类:

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;
	}
}

2.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();
    }

}

3 使用配置

3.1 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 //自定义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 {

}

4 代码设计

1.接口的设计

package cn.edu.sdut.softlab.connectioninterface;

public interface Connection {
	void connect();

	void closeConnection();

	String doSomething();
}

2.实现类的设计

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;
	}

}

3.生成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;
	}
}

4.自定义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 {

}

5.组件注入(重要)

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;
	}
}

5 部署运行

使用命令:

mvn clean package wildfly:deploy

6 代码库

详细完整实例代码请移步:

https://github.com/GaoZiqiang/CDI-Alternative

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值