Bean-Injection failed at Hazelcast map-store class - spring

I wanna inject a bean which will persist the map-entries at hazelcast.
<map name="storethiselements-map">
<backup-count>1</backup-count>
<map-store enabled="true">
<class-name>name.of.MapPersistenceObject</class-name>
<write-delay-seconds>0</write-delay-seconds>
</map-store>
</map>
These are constructor-args for the hazelcast-instance.
In the MapPersistenceObject there exists a Service which is responsible for persisting the entries. I have marked MapPersistenceObject as component and made the Service-Object Autowired so that Spring will inject the right Service-Bean with the right Datasource.
I have tried this but i get a NullPointer where the Service should be injected. It seems to me that Spring can't connect or autowire the MapPersistenceObject with the Service. It looks like this:
#Component
public class MapPersistenceObject implements
MapLoader<Long, DeviceWakeupAction>, MapStore<Long, DeviceWakeupAction> {
#Autowired
StoreMapEntries storeMapEntriesService;
[...]
Maybe somebody knows a solution of the problem?
regards && tia
noircc

You should use Spring configuration, not Hazelcast xml configuration.
<hz:hazelcast id="hazelcast">
<hz:config>
...
<hz:map name="storethiselements-map" backup-count="1">
<hz:map-store enabled="true" implementation="mapPersistenceObject" write-delay-seconds="0"/>
</hz:map>
...
</hz:config>
</hz:hazelcast>
<bean id="mapPersistenceObject" class="name.of.MapPersistenceObject"/>
See Hazelcast Spring integration.

Related

Spring inject bean is always singleton

We are using spring 3.2.
We defined a bean myAccountVO in spring.xml files and set the scope to prototype, but the spring creates this bean as singleton bean.
Here is the spring xml:
<bean name="myAccountVO1"
class="valueobject.AccountVO"
scope="prototype" >
<property name="accountNo" value="0105069413007" />
<property name="accountType" value="01" />
</bean>
The service class is:
#Service //I've tested the #Scope("prototype") but no luck
public class AccountSummary {
#Autowired //I also tested #Resource but same result
private AccountSummaryVO myAccountSummaryVO1;
AccountSummaryVO getAccount(){
return myAccountSummaryVO1
}
}
Later we use this service as:
#Autowired
AccountSummary accountSummary;
............
accountSummary.getAccount()
As far as I get the AccountSummary class, itself, is a singleton and will not be instantiated every time.
It seems are very basic usecase, but I don't know what am I missing.
I don't see where you are injecting myAccountVO1.
But I guess when you reveal the injected place that it's probably a member of a bean which itself is not in the scope prototype, e.g. #Service or #Controller. The service bean will be instantiated with a newly created myAccountVO1, but this instance stays there forever.
Change the scope of the containing bean. See 4.5.3 Singleton beans with prototype-bean dependencies.
This applies as well to the beans which have the service beans injected.

spring: need for an example of using prototype bean in a web environment

I wonder how can I properly inject a prototype bean to a singleton one in a web app. Consider this example:
<bean id="order" class="com.foo.Order" scope="prototype"/>
<bean id="orderService" class="com.foo.OrderService">
<property name="userPreferences" ref="userPreferences"/>
</bean>
I thought of using getBean() but isn't that a way to make my code dependent to spring itself?
I need a short java code example to demonstrate how to inject an order bean in my OrderService singleton.
Thanks
You can use jsr-330 Providers, just put:
#Autowired
Provider<Order> orderProvider;
in your singleton bean, and then use the provider:
public Whatever yourMethod() {
Order order = orderProvider.get();
}

Mule 3.3 TCP Custom Protocol and Spring Injection #Autowired doesn't work

I have problem in Mule when I was using custom tcp protocol and inside the custom protocol has a spring dependency injection using #Autowired annotation.
CustomProtocol.java
public class ContentLengthProtocol extends AbstractByteProtocol{
#Autowired
private Adapter adapter;
#Lookup("atm-inbound")
private ImmutableEndpoint inboundEndpoint;
public ContentLengthProtocol(){
super(true);
}
public Object read(InputStream is) throws IOException{
// do some reading
}
}
Mule Configuration snippet
<spring:beans>
<spring:bean id="adapter" class="id.company.dao.Adapter"/>
<spring:bean id="contentLengthProtocol" class="id.company.protocol.ContentLengthProtocol"/>
</spring:beans>
<tcp:connector name="TCPConnector" validateConnections="true" sendBufferSize="0" receiveBufferSize="1024" receiveBacklog="50" reuseAddress="true" keepAlive="true" clientSoTimeout="0" serverSoTimeout="0" socketSoLinger="0" doc:name="TCPConnector">
<tcp:custom-protocol ref="contentLengthProtocol"/>
</tcp:connector>
<tcp:endpoint name="tcp-inbound" address="tcp://localhost:1234" connector-ref="TCPConnector" doc:name="TCP"/>
<flow name="AdapterFlow" doc:name="AdapterFlow">
<tcp:inbound-endpoint ref="tcp-inbound" doc:name="Inbound TCP"/>
<echo-component doc:name="Echo"/>
</flow>
When the flow reading input and processing read method on ContentLengthProtocol, the adapter always null. But the strange thing is, if i just define ContentLengthProtocol bean but doesn't referenced the bean inside the TCP connector as custom protocol, spring injection works as usual and adapter is not null.
Can someone give me enlightment of what happened here ?
Any help is kindly appreciated.
Thanks.
There's potentially an injection conflict between Mule and Spring annotations. According to the doc, I don't think using #Inject would help either.
So it's probably better to go for the regular Spring injection:
<spring:bean id="contentLengthProtocol"
class="id.company.protocol.ContentLengthProtocol"
p:adapter-ref="adapter"
p:inboundEndpoint-ref="atm-inbound" />
I found the exact problem which alter the #Autowired process. There are some details that I haven't informed, The Adapter class is actually a service that holds a MyBatis mapper. The MyBatis mapper is configured using spring-mybatis integration, org.mybatis.spring.mapper.MapperScannerConfigurer to be specific. This class(bean) scan certain package to be proxied. Somehow If I combine this beans with a spring bean and mule, #Autowired doesn't work, even using <property> to manually inject object into ContentLengthProtocol won't work properly (The Adapter bean is injected, but not the MyBatis mapper class inside the Adapter bean). As a workaround, I managed to make it work using the old and tedious way, which is org.mybatis.spring.mapper.MapperFactoryBean bean. Basically this bean has to be declared for each mapper I have.

Spring injection bind toInstance

Is there a way to bind an injected object to a specific instance using Spring DI similar to Google Guice's
bind(MyClass.class).toInstance(myclassobject);
If the constructor or member variable is annotated with #Autowired, Spring will try to find a bean that matches the type of the Object. You can get similar functionality to the annotation using #Qualifier, for example:
bind(MyClass.class).annotatedWith(Names.named("main")).toInstance(myclassobject);
would become in Spring:
#Autowired #Qualifier("main") private MyClass myClassObject;
<bean name="myClassObject" class="example.MyClassImpl">
<qualifier value="main"/>
</bean>
See http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-autowired-annotation for more.

Spring 3.0.5 doesn't evaluate #Value annotation from properties

Trying to auto-wire properties to a bean in Spring 3.0.5.RELEASE, I'm using:
config.properties:
username=myusername
main-components.xml:
<context:property-placeholder location="classpath:config.properties" />
MyClass:
#Service
public class MyClass {
#Value("${username}")
private String username;
...
}
As a result, username gets set to literally "${username}", so the expression doesn't get parsed. My other auto-wired dependencies on this class get set, and Spring doesn't throw any exception. I also tried to add #Autowired but it didn't help.
If I parse properties to a separate bean and then use #Autowired + #Qualifier, it works:
<bean id="username" class="java.lang.String">
<constructor-arg value="${username}"/>
</bean>
Any ideas how to use just #Value? Maybe I need to include some Spring dependency that I haven't? Thank you
Found what the issue was. Copy/paste from comments:
Are you sure you have <context:property-placeholder> in the same application context as your MyClass bean (not in the parent context)? – axtavt
You're right. I moved <context:property-placeholder> from the context defined by the ContextLoaderListener to the servlet context. Now my values get parsed. Thanks a lot! - alex

Resources