views:

877

answers:

4

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.

+2  A: 

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.

Michael Wiles
Yes, I can configure MyClass in the applicationConfig.xml. The desireto use @Autowire is because several classes in the same package eachneed the same property set. I've updated the original question
Chadwick
You could look at using an "abstract" bean definition. At least then you won't have to declare the property in every bean, all you'll need to do is reference that abstract bean as a parent bean. Problem with using the annotation approach is that you need access to the source code.
Michael Wiles
+1 for the solution in comments.
Chadwick
A: 

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

JamesC
The field is final, not to prevent setting it, but to prevent overriding it's behavior. It is my SqlMapClientFactoryBean that I was trying to get Spring to pass in using @Autowired.
Chadwick
A: 

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.

Chadwick
A: 

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.

yincrash