Можно ли поместить @ManagedBean и @XxxScope в базовый класс?


У меня есть два @ManagedBean (javax.сталкиваться.боб.ManagedBean), родитель и ребенок. Родительский управляемый Боб не является абстрактным, потому что мы должны предоставить разработчику свободу использовать родителя, если этого достаточно, или наследовать его с дочерним элементом, который обладает специфической функциональностью.

У меня есть проблемы с Бобом инъекций и аннотированным методом @PostConstruct в Родительском Бобе.

Следующий код-это единственный способ, которым он работает.

@ManagedBean(name = "myBean")
@SessionScoped
public class BaseBean implements Serializable {
    @ManagedProperty(value = "#{serviceManagerController}")
    protected ServiceManagerController serviceManagerController;

     @PostConstruct
     public void init() {
       //do things
     }
}

И ребенок Боб

public class ChildBean extends BaseBean {
    @PostConstruct
    public void init() {
       super.init();
    }
}

К переопределить Боб" myBean " и заставить приложение использовать дочерний Боб, когда это необходимо, я должен был объявить дочерний боб в faces-config.xml

<managed-bean>
    <managed-bean-name>myBean</managed-bean-name>
    <managed-bean-class>package.ChildBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
        <property-name>serviceManagerController</property-name>
        <property-class>package.ServiceManagerController</property-class>
        <value>#{serviceManagerController}</value>
    </managed-property>
</managed-bean>
Это единственный способ, как все работает, и я не понимаю некоторых вещей.
  1. Если я не объявляю дочерний боб в faces-config.xml, то контейнер beans всегда использует реализацию родительского Боба, хотя @ManagedBean наследуется.
  2. инъекции в родительский Боб, такие как serviceManagerController, не выполняются, пока я не объявлю <managed-property> в faces-config.xml дочернем Бобе декларация.
  3. метод @PostConstruct не выполняется в Родительском дочернем элементе, только в дочернем элементе @PostConstruct. Из-за этого мне приходится вызывать super.init() в пустом @PostConstruct мехтоде в дочернем Бобе

Почему я должен сделать эти три шага, чтобы сделать инъекции и постконструкцию в родительской работе?

Конечно, если в моем приложении я не хочу наследовать BaseBean и хочу использовать этот боб в facelets, все работает без проблем.

С уважением

1 2

1 ответ:

BaseBean неправильно спроектирован. Аннотации управления бобами не наследуются. Технически не имеет смысла иметь несколько экземпляров различных подклассов, зарегистрированных на одном и том же управляемом имени/идентификаторе Бина. Класс BaseBean должен быть abstract и не иметь аннотаций управления бобами (чтобы ни вы, ни JSF не могли "случайно" создать его экземпляр). Вместо этого поставьте управление этими бобами на ChildBean. Ваш faces-config.xml " fix " делает в основном именно это.

public abstract class BaseBean implements Serializable {

    @ManagedProperty("#{serviceManagerController}")
    protected ServiceManagerController serviceManagerController;

    @PostConstruct
    public void init() {
        // ...
    }

    // ...
}
@ManagedBean("myBean")
@SessionScoped
public class ChildBean extends BaseBean {
    // ...
}
Однако управляемые свойства и аннотации post construct / pre destroy наследуются при условии, что вы еще не переопределили их в подклассе. Так что вам не нужно их переопределять.

См. также: