简体   繁体   中英

ClassBridge with DAO class injected

I have a Hibernate Search ClassBridge where I want to use @Inject to inject a Spring 4.1 managed DAO/Service class. I have annotated the ClassBridge with @Configurable . I noticed that Spring 4.2 adds some additional lifecycle methods that might do the trick, but I'm on Spring 4.1

The goal of this is to store a custom field into the index document based on a query result.

However, since the DAO, depends on the SessionFactory getting initialized, it doesn't get injected because it doesn't exist yet when the @Configurable bean gets processed.

Any suggestions on how to achieve this?

You might try to create a custom field bridge provider , which could get hold of the Spring application context through some static method. When provideFieldBridge() is called you may return a Spring-ified instance of that from the application context, assuming the timing is better and the DAO bean is available by then.

Not sure whether it'd fly, but it may be worth trying.

Hibernate Search 5.8.0 includes support for bean injection. You can see the issue https://hibernate.atlassian.net/browse/HSEARCH-1316 .

However I couldn't make it work in my application and I had implemented a workaround.

I have created an application context provider to obtain the Spring application context.

public class ApplicationContextProvider implements ApplicationContextAware {

   private static ApplicationContext context;

   public static ApplicationContext getApplicationContext() {
       return context;
   }

   @Override
   public void setApplicationContext(ApplicationContext context) throws BeansException {
       ApplicationContextProvider.context = context;
   }
}

I have added it to the configuration class.

@Configuration
public class RootConfig {

    @Bean
    public ApplicationContextProvider applicationContextProvider() {
        return new ApplicationContextProvider();
    }

}

Finally I have used it in a bridge to retrieve the spring beans.

public class AttachmentTikaBridge extends TikaBridge {

    @Override
    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {

        // get service bean from the application context provider (to be replaced when HS bridges support beans injection)
        ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
        ExampleService exampleService = applicationContext.getBean(ExampleService .class);

        // use exampleService ...

        super.set(name, content, document, luceneOptions);
    }

}

I think this workaround it's quite simple in comparision with other solutions and it doesn't have any big side effect except the bean injection happens in runtime.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM