7年前くらいに作ったWebLogicで動かしているアプリがあるのですが、Java.faces系のDI実装がだいぶ前から非推奨となっていたので、どこかで対応しないとなあ~と思っていてから数年経ちましたが、時間が取れたのでCDI実装に置き換えてみました。
まず、簡単なところでは、javax.faces.bean.RequestScoped 等のスコープ指定を CDIのjavax.enterprise.context.RequestScoped に、
javax.faces.bean.ManagedBean を javax.inject.Named に
この辺りは単純にimportするライブラリを変更するだけです。ただし、@ViewScopedと@SessionScopedについては、Serializableを実装する必要があるようです。
//import javax.faces.bean.ManagedBean;
//import javax.faces.bean.SessionScoped;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
//@ManagedBean(name = "xxxController")
@Named(value = "xxxController")
@SessionScoped
public class XXXController implements Serializable {
以下略
次に、javax.faces.bean.ManagedProperty ですが、こちらは2パターンの対応が必要となり、@ManagedPropertyでDIしている箇所は、@Injectと@Namedに置き換えるだけです。
public class UserService implements Serializable {
// @ManagedProperty("#{userDto}")
@Inject
@Named("userDto")
UserDto user;"
以下略
ManagedPropertyの別パターンで、今回対象のアプリではxhtmlからのPOSTデータ授受に使用していたのですが、javax.faces.annotation.ManagedProperty に置き換えても動かなかったので、下記のようにFacesContext経由でデータを受け取るようにしました。
public class UserController{
// @ManagedProperty(value=""#{param.data}"")
// private User user;
public String editUser(){
FacesContext context = FacesContext.getCurrentInstance();
User user = (User) context.getApplication().evaluateExpressionGet(context,"#{data}", User.class);
以下略
最後に、アプリでは共有したいセッション情報等を保持する為に、@ApplicationScopedをeager指定してアプリ開始時に生成していたのですが、CDI-APIの方では存在せず、初回コール時のタイミングで生成されるようです。
//import javax.faces.bean.ApplicationScoped;
//import javax.faces.bean.ManagedBean;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
//@ManagedBean(name="XXX",eager=true)
@Named(value = "XXX")
@ApplicationScoped
public class XXXManager {
以下略
参照している箇所も見直しが必要で結果的に下記のように置き換えました。
// XXXManager mgr = (XXXManager) req.getSession().getServletContext().getAttribute("XXX");
XXXManager mgr = CDI.current().select(XXXManager.class).get();
if(mgr == null){
//生成前の時
}
動作は一通り確認しましたが、何か機能が追加された訳でもなく、置き換え前でも動きは変わらないので、いつリリース出来るかなあ。。
