CDI技术第八步 动态BEAN
动态Bean是什么意思呢?
就是我在运行的时候获得动态的东西。如果按我们之前将的方式来做。获得的对象并不是动态的。因为注解加在了类上面,所以在运行时期就是这个实现类,并不能改变。
动态的关键技术就是注解加上方法上,获得的Bean是方法的返回值。既然是方法,那么方法里就可以写各种代码来实现了。这就是动态。
我们可以模拟一个卖饮料的例子。
随机提供实现饮料。这里用到的关键技术就是@Produces注解。
还需要用到的一个重要接口是 javax.enterprise.inject.Instance。
因为这个可以保证动态,否则不是动态的。
废话不多说。上代码:
package com.rschy.cdiproducer;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
@RequestScoped
public class DrinkShop {
@Produces
public String coffee() {
return System.currentTimeMillis()%2==0 ? "Coffee" : "Coco cola";
}
}
这个类表示是一个request作用域的对象,其方法返回值是string,这个返回的string作为一个bean被CDI容器所管理。然后我们的servlet代码就这样写。
package com.rschy.cdiproducer;
import java.io.IOException;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/drink.html")
public class DrinkServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Inject
private Instance<String> drink;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().append("You got a ").append(drink.get()).append(".");
}
}
这里用到Instance接口泛型,可以保证每次都会去取新的对象。如果不用这个接口,改成下面的写法:
@Inject
private Instance<String> drink;
虽然能取到对象,但是对象不会变,哪怕是重新请求了,对象还是原来那个对象简单说就是你感觉到作用域无效了。这是动态CDI bean的特殊性。
我们在浏览器访问试一下:
可以看到两次访问是不同的结果了。