开发者

Can @Autowired by type produce a bean definition?

When you use @Autowired in a spring @Component, spring determines autowire candidates for every instantiation of the component, which is really not good when you use @Request/@Se开发者_C百科ssion scoped web stuff. Why doesn't spring just make a bean definition within the ApplicationContext once and re-use that ? Is there any way to make it do so ?


AutowiredAnnotationBeanPostProcessor is a BeanPostProcessor, not a BeanFactoryPostProcessor, so it can't edit Bean definitions, by design. Implementing that differently would break expected functionality:

public class MyBean{

    @Autowired(required=false)
    public void setOtherBean(OtherBean o){this.otherBean=o;}
    private OtherBean otherBean;

}

If no OtherBean instance is available, none will be wired, but as soon as one becomes available (and I can easily programatically wire one), the next MyBean instance (if scope is not singleton) will get the new OtherBean (which was not available before).

I'm not saying this a use case I have encountered before, but it's a valid use case and it would break if things worked the way you suggest that they should.


Yes: Spring will reuse the component when you set the scope to something else (i.e. you must not use prototype, session or request). So the trick is to use two beans: One which has all the stuff that doesn't change. And one bean which is attached to the session/request and has just a single dependency: the first bean.

Spring can't do this for you since there is no rule when a bean is "static" enough - you as a developer have to determine that.

[EDIT] You have to collect the static parts of the bean (those which won't change over time) in a DAO/service bean. Then use that bean in your @Component -> one lookup.

To speed up the lookup, attach a name to the component. For type-based lookup, Spring has to iterate over the whole context (because several beans could match) while name/ID based lookup is just a lookup in a map.

To give a bean a name, specify it in @Context, or use @Bean(name="name"). To tell Spring which bean to use from the context, use @Resource(name) or @Qualifier("businessObject").


Best practice is to use service classes, components, DAOs etc. as singletons and to have just one instance in an application context.@Component annotation causes just the instaces to be found in component scan process, which means, that they are candidates for auto-scan and living instances in spring context. For example:

@Component
public class StudentDAO {
        @Override
        public String toString() {
                return " inside StudentDAO";
        }
}

StudentDAO is a data access object, and in best practices, more than one instance of this service calss aren't needed in context. It is basically a service class. It is a perfect candidate for a singleton. If there is just one instance of this object around, the autowiring works efficiently too as well 8-) .But you have to still beware of access' on singleton methods and decide to mark your methods as synchronized to prevent unwished effects of threads.


A manual alternative is to inject a singleton-scoped Provider into your beans which provides prototype-scoped beans.

This means that there is more work done by the programmer, but nevertheless the performance hit will be eliminated.


Set the proxyMode attribute of the @Scope annotation on you request / session scoped beans. Spring will create a proxy which will be auto-wired - the proxy will lookup the actual bean which a method is invoked on it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜