2012-06-26 31 views
9

Tôi có BaseBean với @PostConstruct và một bean mở rộng nó trên đó tôi muốn gọi một @PostConstruct khác. Tôi đã đọc một số nơi mà nó nói rằng nó đã có thể, tuy nhiên, có vẻ như các @ postConstruct trên lớp mở rộng được gọi là đầu tiên (nếu thứ hai được gọi là ở tất cả). Sau đó tôi nhận được một NPE về "bối cảnh" bởi vì tôi giả định PostConstruct của siêu đậu đã được gọi.gọi @PostConstruct trên siêu đậu VÀ mở rộng đậu

Điều này có thể thực hiện được không? Nếu vậy tôi đang làm gì sai?

cơ sở đậu:

@ManagedBean 
@RequestScoped 
public class BaseBean { 
@ManagedProperty(value = "#{contextBean}") 
    private ContextBean contextBean; 
    Context context; 
@PostConstruct 
public void setupContext() { 
    context = getContextBean().getContext(); 
} 

Mở rộng đậu:

@ManagedBean 
@RequestScoped 
public class SmartBoxSearchBean extends BaseBean { 
@PostConstruct 
public void setUp() { 
    jsonHelper = context.get(SmartBoxJsonHelper.class); 
} 

Cảm ơn, Yotam.

+0

@YotamSeon Tôi có một vấn đề rất giống [ở đây] (http://stackoverflow.com/q/29787068/330457). Bạn đã kết luận rằng đề xuất được chấp nhận là giải pháp duy nhất bạn có thể làm? –

Trả lời

10

@PostConstruct của siêu lớp của bean sao lưu không được gọi khi nào bean được quản lý được tạo. Nó chỉ được gọi khi hoàn toàn riêng biệt thể hiện bean được quản lý của siêu lớp đó được xây dựng bằng ví dụ: sử dụng #{baseBean} trong EL trong trường hợp của bạn. Bạn có hiệu quả kết thúc với hai trường hợp hoàn toàn riêng biệt #{baseBean}#{smartBoxSearchBean} trong đó phương thức riêng của lớp là @PostConstruct được gọi độc lập trên chính lớp bean được quản lý.

Thiết kế này hơi lạ. Một siêu lớp của bean sao lưu thường không được sử dụng như một bean được quản lý.

Tôi đề nghị sửa đổi cách tiếp cận của bạn như sau:

public abstract class BaseBean { 

    @ManagedProperty("#{contextBean}") 
    private ContextBean contextBean; 

    public Context getContext() { 
     return contextBean.getContext(); 
    } 

} 

@ManagedBean 
@RequestScoped 
public class SmartBoxSearchBean extends BaseBean { 

    @PostConstruct 
    public void setUp() { 
     jsonHelper = getContext().get(SmartBoxJsonHelper.class); 
    } 

} 

Hoặc có lẽ đây, nếu bạn không cần ContextBean cho các mục đích khác ở tất cả các

public abstract class BaseBean { 

    @ManagedProperty("#{contextBean.context}") 
    private Context context; 

    public Context getContext() { 
     return context; 
    } 

} 

Lưu ý rằng @ManagedProperty chỉ hoạt động tốt khi được khai báo trong một siêu lớp này đường.


Cập nhật: tùy thuộc vào yêu cầu chức năng, bạn cũng có thể tách đậu và chỉ cần tiêm #{baseBean} trong {smartBoxSearchBean}.

@ManagedBean 
@RequestScoped 
public class BaseBean { 

    @ManagedProperty("#{contextBean}") 
    private ContextBean contextBean; 
    private Context context; 

    @PostConstruct 
    public void init() { 
     context = contextBean.getContext(); 
    } 

} 

@ManagedBean 
@RequestScoped 
public class SmartBoxSearchBean { 

    @ManagedProperty("#{baseBean}") 
    private BaseBean baseBean; 

    @PostConstruct 
    public void setUp() { 
     jsonHelper = baseBean.getContext().get(SmartBoxJsonHelper.class); 
    } 

} 
+1

Cảm ơn BalusC vì câu trả lời siêu nhanh. Giải pháp của bạn sẽ hoạt động, ngoại trừ một vấn đề - Trong PostConstruct của BaseBean tôi cũng khởi tạo các thành viên khác, rằng các bean mở rộng sử dụng ... –

+0

Xem cập nhật câu trả lời. – BalusC

+0

Cảm ơn bạn lần nữa, triển khai! –

Các vấn đề liên quan