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

一、知识储备

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

二、produces概念讲解

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

2.1 produces动态注入的理解

其实本人对于produces的”动态注入”理解的也不是很深刻。
可以这样理解:
CDI的@Qualifier和@Alternative注解强调的是注入不同的组件,本质上是注入一个实现类的对象,而@Produces强调的是在不同的情景下注入不同的方法,从而实现”动态注入”的目的。

2.2 辨析:

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

}
  • 三、使用配置

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 {

}

四、代码设计

接口:

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

你可能感兴趣的:(CDI系列学习--produces动态注入注解的使用和讲解)