Tôi đang sử dụng để sử dụng Spring để làm dependency injection tôi như vậy:Sử dụng mô hình Hibernate 4 của tích hợp và dependency injection Spring
<context:component-scan base-package="org.emmerich.myapp" />
và sau đó chú thích các lớp học phụ thuộc của tôi với Autowired
như vậy:
public class DependentClass {
@Autowired
private Dependency dependency;
}
Tuy nhiên, với những thay đổi trong Hibernate 4.0, chúng tôi hiện khuyên bạn nên sử dụng giao diện Integrator
mới để khám phá dịch vụ. Điều này bao gồm việc thêm trình xử lý sự kiện cho các trình kích hoạt như postUpdate
, postDelete
v.v.
Thật không may, điều này không chơi độc đáo với việc tiêm phụ thuộc thông qua các phụ thuộc có chú thích. Tôi có thiết lập sau:
Trình tích hợp tôi đã xác định để thêm người nghe của mình vào ServiceFactory
. Điều này được tham chiếu trong tập tin META-INF/services/org.hibernate.integrator.spi.Integrator
.
public class MyIntegrator implements Integrator {
private MyListener listener;
public MyIntegrator() {
listener = new MyListener();
}
@Override
public void integrate(Configuration configuration,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
final EventListenerRegistry eventRegistry =
serviceRegistry.getService(EventListenerRegistry.class);
eventRegistry.prependListeners(EventType.POST_COMMIT_INSERT, listener);
}
Tôi cũng đã xác định lớp học MyListener
, trông giống như người nghe sự kiện điển hình của bạn.
@Component
public class MyListener implements PostInsertEventListener {
@Autowired
private Dependent dependent;
public void onPostInsert(PostInsertEvent event) {
// dependent == null
}
}
May mắn thay, như được hiển thị trong nhận xét, điều này không hiệu quả. Tôi đoán đó là vì tôi đang instantiating MyListener
bên trong MyIntegrator
, nó không nhận các thành phần và không autowire thành phần. Tuy nhiên, nếu tôi thử điều này:
@Component
public class MyIntegrator {
@Autowired
private MyListener listener;
...
}
Sau đó, người nghe không được tự động.
Thứ nhất, cảm thấy sai khi sử dụng Spring phải làm new MyListener()
. Tôi mong đợi để có thể xác định rằng như là một phụ thuộc autowired và có mùa xuân tạo ra một singleton cho tôi. Câu hỏi của tôi là:
Cách tiếp cận tốt nhất để sử dụng tiêm phụ thuộc với giao diện Tích hợp mới là gì? Các bộ tích hợp được sử dụng để xây dựng một SessionFactory, và vì vậy khi chúng được yêu cầu tích hợp chúng, tôi đoán không có một ngữ cảnh ứng dụng có sẵn. Do đó, bất kỳ hạt cà phê nào tôi yêu cầu trong Trình tích hợp cần được tạo theo cách "cũ kỹ" và sẽ không nhận được sự tự động trên chúng.
Tôi khá mới với thế giới của mùa xuân, bạn có nói đây là điều mà tôi nên trông đợi không? Tôi hiểu rằng tôi đang ở trong một phạm vi khác nhau của ứng dụng khi tôi đang trong SessionFactory, nhưng có cách nào để có được một tham chiếu đến đậu và cho phép autowire mặc dù tôi đang tạo nó qua new
?
Giải pháp tôi đã sử dụng ApplicationContextAware
. Nó có nghĩa là MyListener
nhận được một tham chiếu đến ApplicationContext
bất cứ khi nào bối cảnh có sẵn, và tôi đã tham chiếu các bean từ ngữ cảnh trên các cuộc gọi phương thức, thay vì xây dựng bean. Tạo một hạt đậu với new
không giới hạn điều này, do đó, Spring vẫn cung cấp cho tôi ngữ cảnh ứng dụng:
@Component
public class MyListener implements PostInsertEventListener, ApplicationContextAware {
private static ApplicationContext context;
public void onPostInsert(PostInsertEvent event) {
// getDependent() == correct!
}
public void setApplicationContext(ApplicationContext context) throws BeanException {
this.context = context;
}
public Dependent getDependent() {
return context.getBean(Dependent.class);
}
}
Có cách nào tốt hơn không?
Bạn không quên thành phần quét 'MyIntegrator 'lớp trong ví dụ' @ Autowired' của bạn? Ngoài ra, ai đang khởi tạo lớp 'MyIntegrator'? –
Đây chính xác là giải pháp mà tôi đã đưa ra. Của nó làm việc tốt đẹp nhưng các appcontext tĩnh chỉ cảm thấy một chút bẩn :) tôi chỉ không tìm thấy một cách đẹp hơn kể từ khi ngủ đông là tạo ra các Integrator. Một khi tôi sẽ có thời gian tôi muốn làm cho điều này trừu tượng hơn và có một tích hợp mà chỉ là một liên kết để có thể đăng ký người nghe, vv được tạo ra bởi mùa xuân. Tôi đã tìm thấy một blog nhưng tôi không thể nhớ được url ngay bây giờ. –
@SotiriosDelimanolis Hibernate tạo 'Integrator' cho bạn. Bạn chỉ định một tệp văn bản trong thư mục 'META-INF/services' của bạn trỏ đến danh sách các trình tích hợp bạn muốn khởi tạo và Hibernate xây dựng chúng cho bạn trước khi tạo SessionFactory. Tôi hiểu rằng không thể sử dụng các thành phần Autowire trong Trình tích hợp - nó được xây dựng bên ngoài phạm vi của ứng dụng. Tuy nhiên, tôi nghĩ rằng có thể sử dụng @Autowired trong trình nghe. Và có, tôi là bối cảnh quét tất cả các lớp học liên quan. – EMMERICH