Can I annotate an inherited final property with #Autowire? - java

Resolution: No I'm no longer extending the original parent.
Original:
Is there a way to annotate an inherited final setter method? I am extending a class which has a final setter which I would like to #Autowire with Spring. The parent class is from a library and cannot be modified.
A workaround I have found is to write a proxy method, but this seems like more work than necessary.
public abstract class SqlMapClientDaoSupport ... {
public final void setSqlMapClient(SqlMapClient smc) {
...
}
}
#Component
public class AccountDao extends SqlMapClientDaoSupport {
// all this just to annotate an existing method?
#Autowire
public final void setSqlMapClientWorkaround(SqlMapClient smc) {
super.setSqlMapClient(smc);
}
}
Edit 1: Above example modified to reflect use case:
The use case is implementing DAO objects for Ibatis/Spring
which extend a common base class. Each DAO needs the same
property set, and each needs to be configured as a bean. I currently
do this by configuring each individually in applicationContext.xml.
<bean id="accountDAO"
class="com.example.proj.dao.h2.AccountDAOImpl"
p:sqlMapClient-ref="sqlMapClient" />
<bean id="companyDAO"
class="com.example.proj.dao.h2.CompanyDAOImpl"
p:sqlMapClient-ref="sqlMapClient" />
<!-- etc... -->
I would prefer to use component-scan to discover and autowire the DAO
objects automatically, which I can't copy/paste botch.
<context:component-scan base-package="com.example.proj.dao.h2" />
I do not see in the annotation guide how one would annotate a
property/member other than where declared. I'm hoping that is
something I'm missing though.
Edit 2: I am no longer extending the SqlMapClientDaoSupport class, instead my AccountDao is a POJO which implements what little functionality was being provided by the Support class. This allows me to use #Autowire at will.

Have you tried configuring it with xml? Because it's an existing class which it looks like you can't change, it's a definite candidate for configuring it with xml. Then you can specify it as autowire", or even configure the property in the xml.

It sounds to me like you shouldn't be trying to set a final field.
There is usually a good reason why fields are final.
Have you setup a SqlMapClientFactoryBean object ?
See here for help

No, there is no way to annotate an inherited final method.
Rather than extend the support class (SqlMapClientDaoSupport) I reimplemented it in my project (it's behavior is minimal) annotating the methods as needed, and my DAO extend that support class.

You could create a new constructor with params for all the setters that are final and #Autowired the constructor, then call the setters in the constructor.

Related

Eclipse RCP - Injecting interfaces marked with #Singleton

I have the following code:
public interface DummyInterface {
}
and
#Singleton
#Creatable
public class DummyInterfaceImpl1 implements DummyInterface {
}
And when I want I can simply inject this, and it works just fine, (see below):
#Inject
DummyInterfaceImpl1
However I can't do
#Inject
DummyInterface
Because I get an
Unable to process "ClassWhereIInject.dummyInterface": no actual value was found for the argument "DummyInterface".
So, I am trying to understand, if I use the combination of #Creatable and #Singleon, without adding the instance that I want to inject in the IEclipseContext, then I can only inject implementation classes and not interfaces?
I can see how this can get problematic, especially when one has multiple implementation classes for the same interface, and the dependency injection framework doesn't know which to inject...that is if you don't use the #Named annotation to specify...
The injection system only looks for something with the name you specify. It does not try and find a class that happens to implement that interface. So no you can't use an #Creatable class with a different name to the interface.
An alternative is to use a 'ContextFunction'. This is a function which is called when the injection system is looking for a name. The context function can create an instance of something suitable and put it in the context for the injector. Full details on context function are here

Mocking an abstract class with a mocked constructor argument?

I'd like to use Mockito to unit test an abstract class as detailed in this great answer.
The trick is, the abstract class has a dependency on a strategy that gets injected in its constructor. I've created a mock of the strategy and I'd like for my mocked instance of BaseClass to use the mocked strategy for my unit test.
Any suggestion as to how I can wire this up? I'm not currently using any IoC framework, but am considering Spring. Perhaps it would do the trick?
// abstract class to be tested w/ mock instance
abstract BaseClass
{
// Strategy gets mocked too
protected BaseClass( Strategy strategy)
{
...
}
}
Update:
According to the Mockito mailing list, there currently isn't a way to pass arguments to the constructor of a mock.
I ended up just using reflection to set a private field in my base class, like so:
// mock the strategy dependency
Strategy strategyMock = mock( Strategy.class);
when(....).thenReturn(...);
// mock the abstract base class
BaseClass baseMock = mock(BaseClass.class, CALLS_REAL_METHODS);
// get the private streategy field
Field strategyField = baseMock.getClass().getSuperclass().getDeclaredField("_privateStrategy");
// make remove final modifier and make field accessible
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(strategyField, strategyField.getModifiers() & ~Modifier.FINAL);
strategyField.setAccessible(true);
// set the strategy
strategyField.set(baseMock, strategyMock);
// do unit tests with baseMock
...
It would break if the name of the private field ever changed, but its commented and I can live with that. It's simple, it;s one line of code and I find this preferable to exposing any setters or having to explicitly subclass in my tests.
Edit: So it's not one line of code anymore since my private field needed to be 'final', requiring a some extra reflection code to get around.
Ive seen this sort of thing done using Mockito at a spring context level.
eg:
<bean id="myStrategy" name="myStrategy" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="Strategy" />
</bean>
I hope that helps.
You don't need to do anything special. Just mock the bean like normal:
Bean bean = mock(Bean.class);
when(bean.process()).thenReturn(somethingThatShouldBeNamedVO);
Just works :)

Howto inject simple config parameters to beans using Guice?

Is there a simple way to inject simple primitive type parameters (string and int) to the beans?
What i need is to find the guice equivalent of something like this from spring.xml:
<bean id="aBean" ...>
<property name="fieldName" value="aStringValue"/>
<property name="anotherFieldName" value="123"/>
</bean>
The values could be constructor injected, field injected or method injected, but i don't want to use separate named annotation or factory or provider for every value that i need to pass to the bean.
EDIT: my solution
Here is what i finally came to. I think it is closest to what i'm looking for, but any improvements would be welcome.
I found that in the module, i can declare a provider method and use it to set any properties i need:
MyModule extends AbstractModule{
...
#Provides #Named("testBean") MyTestBean createTestBean(MembersInjector<TestBean> mi){
TestBean test = new TestBean();
mi.injectMembers(test);
test.setFieldName("aStringValue");
test.setAnotherFieldName(123);
return test;
}
...
}
The good point is that the Provides method replaces the bind() for the bean and this way the actual line count doesn't increase much.
I'm still not 100% sure about any side effects, but it looks promising.
There is a build in mechanism to inject properties.
Properties File:
name=jan
city=hamburg
Module
#Override
protected void configure() {
Names.bindProperties(binder(), properties);
}
then in your bean, just inject by Name
class Customer {
#Inject
#Named("name")
String name;
....
}
There are a couple different ways you could do this, including your way. The only drawback to using a Provider method is that it's essentially a hand-rolled factory that you have to remember to maintain. (And in this specific case, you're also not getting the benefits of constructor injection).
Absent a Provider method, you have to use a binding annotation of some kind. If #Named won't work for you, then you'd need to create an annotation for each binding.
bindConstant().annotatedWith(FieldName.class).to("aStringValue");
public SomeClass {
public void setFieldName(#FieldName String fieldname) {}
}
In some cases this might require a 1-to-1 annotation per primitive/String instance to be bound. But I try to make my annotations somewhat orthogonal to the actual instance being described, preferring instead to use the annotation to describe the relationship between the bound objects and the injection points.
It's not always possible, but a whole group of related primitives could then potentially be described by a single binding annotation, as long as each primitive type is only used once in the set. So, this could hypothetically work:
bindConstant().annotatedWith(MyAnnotation.class).to("aStringValue");
bindConstant().annotatedWith(MyAnnotation.class).to(123);
Parenthetically, I'm curious why you can't used #Named annotations on the property, but you can use them on the injected bean?

Using the instance factory method to create prototype beans dynamically

I have a situation where I would like to dynamically create an object through a factory object, but the object needs to be created through the spring context, to allow autowiring of dependencies. I know that there are lots of other ways that I can solve this problem - using a service locator pattern for example - but I'd like to do it this way if possible.
Imagine I have two objects:
class OuterObject {
List<InnerObjectInterface> innerObjs;
...
}
class InnerObject implements InnerObjectInterface{
#Autowired
SomeDependency someDependency;
...
}
I want to create a factory that does something along the lines of:
class OuterObjectFactory {
private innerObject = new InnerObject();
public OuterObject construct(params){
OuterObject o = new OuterObject();
List<InnerObjectInterface> inners = new ArrayList<InnerObjectInterface>();
...
for(some dynamic condition){
...
inners.add(createInnerObject());
...
}
}
public createInnerObject(){
return innerObject;
}
}
My spring-context.xml would looks something like:
<bean id="outerObjectFactory" class="path.OuterObjectFactory" />
<bean id="innerObject" class="path.InnerObject" factory-bean="outerObjectFactory" factory-method="createInnerObject" />
This however, doesn't work. Only one innerObject is ever created, where I want it to act like it has scope="prototype". If I add scope="prototype" to the bean definition:
<bean id="innerObject" class="path.InnerObject" factory-bean="outerObjectFactory" factory-method="createInnerObject" scope="prototype"/>
Then it seems to create many innerObjects, but they aren't correctly wired. My co-worker believes that the documentation found here implies that the factory bean is only used to initialize a bean, but I don't find that obvious.
I'd appreciate it if anyone could clear up my understanding here, and possibly even suggest a better way of modelling the factory pattern with wiring than what I am doing.
Thanks!
I think what you're saying is that you have a factory which is a singleton and you want it to create new objects of which you want a new one each time with full dependency injection. The old way of doing that was Method Injection which you link to above. The new (and arguably cleaner way) is to use a Scoped Proxy. You can either use annotations or regular config but the idea is that you create a proxy around the bean (e.g. the InnerObject). When ever you need a reference to it, spring will automatically provide you with a new copy with the appropriate dependencies inserted.

Applying same annotation on multiple fields

Is it possible to apply same annotation on multiple fields (if there are many private fields and it just looks awkward to annotate them all.
So What I have is like
#Autowired private BlahService1 blahService1;
#Autowired private BlahService2 blahService2;
#Autowired private BlahService3 blahService3;
and so on
I tried the following but it won't work
#Autowired{
private BlahService1 blahService1;
private BalhService2 blahService2;
}
Some thing fancy with custom annotations perhaps?
No, but you could annotate your constructor rather than your fields. This would have the additional benefit to make your class more easily testable, by injecting mock dependencies when constructing the instance to test (which is the main reason why dependency injection is useful) :
#Autowired
public MyClass(BlahService1 blahService1, BlahService2 blahService2, BlahService3 blahService3) {
this.blahService1 = blahService1;
this.blahService2 = blahService2;
this.blahService3 = blahService3;
}
There's nothing built-in to the language that allows that kind of multi-annotations.
Many frameworks however opt to allow some kind of "default-annotation" on the class level.
For example, it would be possible for the framework to allow an #Autowired annotation at the class level to imply that each field should be auto-wired. That's entirely up to the framework to implement, however.
You can try extending AutoWired annotation interface with setting default values of fields, setting its target type to fields, and whenever it is not required you can turn it of by passing appropriate values to annotations on only those fields.

Categories