Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

injecting derived property for @Repository bean without @Autowired in super class

I would like to use @Repository spring annotation to avoid adding bean in context.xml. I use ibatis integration, so my repository class looks like this

@Repository("userDao")
public class UserDaoMybatis extends SqlMapClientDaoSupport implements UserDao {
    // ...
}

SqlMapClientDaoSupport (spring library class) has final method for setting required property which is not annotated with @Autowired or @Resourse

public final void setSqlMapClient(SqlMapClient sqlMapClient) {
    if (!this.externalTemplate) {
        this.sqlMapClientTemplate.setSqlMapClient(sqlMapClient);
    }
}

SqlMapClient bean is defined in spring context.xml. If userDao bean is defined in XML it works fine, but when I put @Repository annotation and remove bean declaration I get the following exception

java.lang.IllegalArgumentException: Property 'sqlMapClient' is required

A workaround can be to add new method like

@Aitowired
injectSqlMapClient(SqlMapClient sqlMapClient) {
    setSqlMapClient(sqlMapClient);
}

but it looks ugly

Is there any other way yo inject the property without having defined?

like image 934
Eugene Platonov Avatar asked Sep 27 '10 20:09

Eugene Platonov


People also ask

What can I use instead of Autowired?

Multiple classes which fit the @Autowired bill You can indicate a @Primary candidate for @Autowired. This sets a default class to be wired. Some other alternatives are to use @Resource, @Qualifier or @Inject. Read more here.

Is @autowired still needed?

So, if more than one Constructor is defined in the Spring bean, then at least one must be annotated with the @Autowired. As of Spring Framework 4.3, an @Autowired annotation on such a constructor is no longer necessary if the target bean only defines one constructor to begin with.

Is @autowired optional?

Before Spring 4.3, we had to add an @Autowired annotation to the constructor. With newer versions, this is optional if the class has only one constructor.

Is @autowired deprecated?

This option was used for autowire by constructor or byType, as determined by Spring container. Since we already have so many options, this option is deprecated.


1 Answers

How about introducing an intermediary superclass?

public class AutowiringSqlMapClientDaoSupport extends SqlMapClientDaoSupport {

   @Autowired
   injectSqlMapClient(SqlMapClient sqlMapClient) {
      setSqlMapClient(sqlMapClient);
   }
}

and then

@Repository("userDao")
public class UserDaoMybatis extends AutoringSqlMapClientDaoSupport implements UserDao {
    // ...
}

Yes, it's abuse of inheritance, but no worse than the existing SqlMapClientDaoSupport, and if you're desperate to avoid the injection hook in the DAO class itself, I can't think of a better way.

like image 116
skaffman Avatar answered Nov 15 '22 09:11

skaffman