CDI的装饰模式有两个十分重要的注解。@Decorator与@Delegate
@Decorator加上类上面,表示这个类是一个装饰器类。@Delegate加上在装饰器的字段上面,用来注入被装饰的对象。
装饰类和被装饰对象实现同一个接口,实现装饰。
首先写一个接口。
package cdidecorator;
public interface HelloInterface {
String greeting();
}
然后写一个实现类
package cdidecorator;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Default;
@RequestScoped
@Default
public class HelloBean implements HelloInterface{
public String greeting(){
return "Hello, world!";
}
}
然后对这个实现类进行装饰。
package cdidecorator;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.enterprise.inject.Default;
import javax.inject.Inject;
/**
* 这是个装饰器
* @author Monkey
*
*/
@Decorator
public class HelloDecorator implements HelloInterface{
/**这里注入默认的实现类*/
@Default
@Inject
@Delegate
private HelloInterface bean;
@Override
public String greeting() {
// 这里覆盖默认的实现类,类似于代理
return "Bonjour, tout le monde! "+bean.greeting();
}
}
但是这样写完了装饰类并没什么用。还需要在WEB-INF/beans.xml
中进行配置,才能让装饰类正式生效。
<?xml version="1.0" encoding="utf-8"?>
<beans>
<decorators>
<class>cdidecorator.HelloDecorator</class>
</decorators>
</beans>
然后就可以写servlet试一试装饰模式啦。
package cdidecorator;
import java.io.IOException;
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("/hello.html")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Inject
private HelloInterface helloBean;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().append(helloBean.greeting());
}
}
运行结果就是下图了: