Prevent Spring from meddling with CDI annotations even for factory created instances - spring

I have a legacy product's JAR that contain Spring (4.3.8) managed classes. I need to integrate it with CDI (JavaEE 7).
I have an interface from the legacy JAR, that is implemented by a CDI bean. The CDI bean is requested from the CDI BeanManager and returned from a factory method. The factory method is registered inside Spring XML and works as expected.
The problem occurs, when a Spring bean of the legacy JAR depends on the implemented interface. Spring than injects the CDI implementation instance and scans the class it for known annotations, namingly #Inject. It then tries to resolve the dependency, which doesn't work since the dependency is not available to Spring.
I already tweaked context:property-placeholder excludes, but that changes nothing.
So how can I tell Spring to stop trying to inject something in my factory produced bean instance?

I finally was able to solve (work around) the problem. I had to remove all CDI-Annotations in the legacy JAR (by replacining them with their Spring counterparts), so spring would any longer work.
Then I added the following XML block to the applicationContext.xml of my CDI WAR:
<context:component-scan annotation-config="false" base-package="com.example">
</context:component-scan>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
<property name="autowiredAnnotationTypes">
<set>
<value>org.springframework.beans.factory.annotation.Autowired</value>
<value>org.springframework.beans.factory.annotation.Value</value>
</set>
</property>
</bean>
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />
<bean class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
<property name="customQualifierTypes">
<set>
<value>org.springframework.beans.factory.annotation.Qualifier</value>
</set>
</property>
</bean>
Basically that drops the support for #Inject, etc. from Spring and leaves it where it belongs: CDI.

It's a bit easier.
AutowiredAnnotationBeanPostProcessor is already a bean, so you can configure it before Spring starts to scan with a ServletContextListener to exclude #Inject annotations. At least from Spring 4.1+, AutowiredAnnotationBeanPostProcessor has a method setAutowiredAnnotationTypes, e.g.:
#WebListener
public class ApplicationConfigListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent event) {
ApplicationContext appCtx = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<Class<? extends Annotation>>();
AutowiredAnnotationBeanPostProcessor bean = appCtx.getBean(AutowiredAnnotationBeanPostProcessor.class);
autowiredAnnotationTypes.add(Autowired.class);
autowiredAnnotationTypes.add(Value.class);
bean.setAutowiredAnnotationTypes(autowiredAnnotationTypes);
}
}
You could use a SpringBeanAutowiringInterceptor too.
This is explained here.

Related

spring batch: inject main application context #Component using AutomaticJobRegistrar

I'm trying to inject some #Service / #Repository bean defined in main application context into some jobs loaded by AutomaticJobRegistrar.
<bean class="org.springframework.batch.core.configuration.support.AutomaticJobRegistrar">
<property name="applicationContextFactories">
<bean class="org.springframework.batch.core.configuration.support.ClasspathXmlApplicationContextsFactoryBean">
<property name="resources" value="classpath*:/META-INF/jobs/*Job.xml" />
</bean>
</property>
<property name="jobLoader">
<bean class="org.springframework.batch.core.configuration.support.DefaultJobLoader">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
</property>
</bean>
Using #Autowired inside my ItemWriter implementation class do not inject my services beans.
I have to enable component scanning inside each *Job.xml or declare each bean in order to make injection works, but injected classes are not the same instance of that one used by main application context.
How can I get the same instance bean declared in main application context?
Thank you for any advice
Did you activate context:annotation-config for each job?
If a new applicationcontext is created for every Job you need to activate this or no annotationprocessing (including #Autowired) will happen.
'context:component-scan' also activates 'context:annotation-config' so this might be the reason #Autowired works if you activate it.

Ehcache and spring bootstrapcacheloader not working

I am trying to setup a bootstrapcacheloader which will query the database and populate the cache. Here I am using ehcache integrated with spring. But the problem is that I am not able to get the dependencies wired into my cacheloader implementation. The #Autowired,#Resource,#Configurable none of them seem to work. Quite obviously the cacheloader instantiation is not done by Spring container , but is there a way I can inject a spring created cacheloader instance into the cachemanager and bootstrap it?
My implementation details below.
ehcache.xml
<cache name="MyCache"
maxElementsInMemory="100000"
eternal="false"
overflowToDisk="false"
timeToLiveSeconds="500">
<!-- <pinning store="localMemory"/> -->
<bootstrapCacheLoaderFactory class="net.tristargroup.claims.helper.ClaimsCacheLoaderFactory" properties="bootstrapAsynchronously=true"/>
<cacheEventListenerFactory class="net.tristargroup.claims.helper.TristarCacheEventListenerFactory" listenFor="all"/>
</cache>
Spring Context xml
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager"><ref local="ehcache"/></property>
</bean>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" depends-on="cacheLoader">
<property name="configLocation" value="classpath:ehcache.xml"/>
</bean>
Cache loader class
#Configurable
public class ClaimsCacheLoaderFactory extends BootstrapCacheLoaderFactory{
#Resource
CacheManager cacheManager;
.
.
.
#Override
public BootstrapCacheLoader createBootstrapCacheLoader(Properties arg0) {
System.out.println("Create cache loader method . Cache manager is ->"+cacheManager);
BootstrapCacheLoader cacheLoader = new ClaimsCacheLoader();
return cacheLoader;
}
The cacheManager instance is always null here even if I specify it as an Autowired attribute.
The problem is present even in the cache event listeners.
Someone please help me on this.
If the cacheManager is null, Tthat means you haven't made the bean available to your package. Add a #ComponentScan("yourpackage") in the same place you defined your bean and add #Component where you want to use your cacheManager.
This is old, but i hope it helps someone else.

Spring loading properties from a bean

I am currently usinmg PropertyPlaceholderConfigurer to load properties into my spring context, however I want to have a custom hierarchy/overriding of property files that I am handling in a Java class. Can I have my class, which itself is a bean in the context, inject the properties into the context?
e.g.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:/config/conf.properties" />
</bean>
<bean id="config" class="com.main.Config" />
My Config class has a Properties getProperties() method -- can I wire that into spring somehow? Obviously the properties would not be loaded until the config bean is created or inited.
Thanks!
Update: As suggested by the answer I change my Config to Config extends PropertySource<Properties> and had to write a small wrapper around MutablePropertySources that takes a single PropertySource and then my xml looks like this:
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="propertySources">
<bean class="com.main.ConfigMutablePropertySources">
<constructor-arg name="propertySource" ref="config" />
</bean>
</property>
</bean>
Where:
public class ConfigMutablePropertySources extends MutablePropertySources {
public ConfigMutablePropertySources(PropertySource<?> propertySource) {
super(new MutablePropertySources());
addLast(propertySource);
}
}
Looking at the methods available (from JavaDoc for PropertyPlaceholderConfigurer) suggests to me no easy way to do such a thing.
The general comment at the top suggests that, as of Spring 3.1, one should prefer to use PropertySourcesPlaceholderConfigurer instead. Using this solution, it appears that you could register your own set of PropertySource objects via the setPropertySources(...) method. Of course your Config class would have to be fit into the interface (abstract class actually) of PropertySource.
It is worth noting that using the setPropertySources(...) method above will assume nothing else about your property sources and will therefore not add the default property sources (Environment and Local properties).

Why is autowiring required? What is the explanation of the concept of autowiring?

Why is autowiring required? What is the explanation for the concept of autowiring?
#autowired annotation in Spring Framework.
Autowiring is not required, just convenient.
It means that if you have a property that requires an InterfaceA and a single bean has been declared in Spring that is of type InterfaceA, instead of using XML to manually "wire up" the relationship (setting a bean reference as a property of another), you can let Spring do the wiring for you.
This is a common question for the beginners. As the beans are injected using DI (setter injections, constructor injections), why do we need auto-wiring? Auto-wiring also doing the same thing, right?
The answer is, it saves you from writing more code.
If using an XML file, using autowire attribute saves you from writing the wiring code in the bean definition.
Please look at code below.
Configuration code without Auto-wiring:
<bean id="employee" class="com.Employee">
<property name="name" value="Dexter"></property>
</bean>
<bean id="employeeService" class="com.EmployeeService">
<property name="employee" ref="employee"></property>
</bean>
Configuration code with Auto-wiring:
<bean id="employee" class="com.Employee">
<property name="name" value="Dexter"></property>
</bean>
<bean id="employeeService" class="com.EmployeeService" autowire="byName" />
Note that we did not have to write anything to refer property of EmployeeService, i.e., Employee. But still it was injected. Autowiring makes the container to search the bean configurations and do the collaboration among beans, without the developer specifically mentioning these.
If we use annotation, even we don’t have to write anything in XML files, including this autoware="byName", etc. Simply #Autowired on bean's setter/field/constructor is sufficient.

Wicket with Spring declarative transaction

It is possible to use the Spring Framework's #Transactional support outside of a Spring container. In reference documentation is chapter about AspectJ aspect. I'm trying to use it in my wicket application, but with no positive result.
application-context.xml:
<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj" />
<context:annotation-config />
<context:component-scan base-package="com.wicket.app"/>
<context:spring-configured />
<bean id="annotationTransactionAspect" factory-method="aspectOf"
class="org.springframework.transaction.aspectj.AnnotationTransactionAspect">
<property name="transactionManager" ref="transactionManager"></property>
</bean>
In my form class annotated by #Configurable, I have:
#Transactional
public void process(IFormSubmittingComponent submittingComponent) {
super.process(submittingComponent);
getDao().getEntityManager().flush();
}
Stack trace:
org.apache.openjpa.persistence.TransactionRequiredException: Can only perform operation while a transaction is active.
You might be able to get this working using AspectJ load-time-weaving, but that's a very complex solution for a simple problem.
If you need declarative transactions, then I suggest you move the transactional logic from the wicket component down into a Spring bean, and invoke the Spring bean from the wicket object. The Spring bean would have the transactional annotations, and would be proxied correctly by the Spring container.
I have no experience with Wicket. But is your 'form class' (the one that contains method annotated with #Transactional) Spring managed code? i.e. Who creates the instances of the class?
If it's not, that Spring will not provide #Transactional support (neither will #Autowired work, etc).

Resources