简体   繁体   中英

Spring component-scan without autowiring?

Does it makes sense to use component-scan WITHOUT using autowiring on spring?

I like the idea of having component scan on an MVC environment for controllers, hell I even like to avoid declaring all the DAOs, Services ... on the xml.

However I am not a big fan of autowiring, so, would it still be possible to manually inject the desired beans using the xml config file or is it just a non-sense?

UPDATE : What would be the advantage of using @Autowired instead of explicit declaration via XML (please do not provide "less xml configuration" as an advantage)

I would

  • add @Component to the implementation classes so that a bean will get created for each of them
  • not associate @Autowired / @Resource with the member declarations corresponding to these implementations in other classes so that Spring cannot autowire them.
  • define the beans where these component beans are needed, in XML using the <bean> node and <property> elements to inject them through setters or <constructor-arg> to inject them through constructors.

Example:

Interface:

package com.krovi.compscan;

public interface MyInterface
{
    void method();
}

Implementation declared as component for Spring DI framework to create a bean for this:

package com.krovi.compscan;

import org.springframework.stereotype.Component;

@Component
public class MyImpl implements MyInterface
{
    public void method()
    {
        System.out.println("Method definition in the implementation");
    }
}

A typical client who would use the component-based bean but injected explicitly through configuration file, through constructors.

package com.krovi.compscan;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyClient
{
    private MyInterface myInterface;

    public MyClient(MyInterface i)
    {
        this.myInterface = i;
    }

    public void clientMethod()
    {
        myInterface.method();
    }

    // Main method to test.    
    public static void main(
        String[] args)
    {
        ClassPathXmlApplicationContext context =
            new ClassPathXmlApplicationContext("classpath:META-INF/compscan.xml");
        MyClient client =
            context.getBean(MyClient.class);
        client.clientMethod();
    }
}

Another typical client who would use the component-based bean but injected explicitly through configuration file using setters:

package com.krovi.compscan;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyAnotherClient
{
    private MyInterface impl;

    protected MyAnotherClient()
    {

    }

    public MyInterface getImpl()
    {
        return impl;
    }

    public void setImpl(
        MyInterface impl)
    {
        this.impl = impl;
    }

    public void clientMethod()
    {
        impl.method();
    }

    public static void main(
        String[] args)
    {
        ClassPathXmlApplicationContext context =
            new ClassPathXmlApplicationContext("classpath:META-INF/compscan.xml");
        MyAnotherClient client =
            context.getBean(MyAnotherClient.class);
        client.clientMethod();
    }
}

Bean configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<beans 
    xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- Component scan to create beans for @Component classes -->
    <context:component-scan base-package="com.krovi.compscan" />

    <!-- Explicit bean declaration for clients to get the 
         @Component classes injected 
    -->
    <bean id="myClient" class="com.krovi.compscan.MyClient">
        <constructor-arg ref="myImpl" />
    </bean>
    <bean id="anotherClient" class="com.krovi.compscan.MyAnotherClient">
        <property name="impl" ref="myImpl" />
    </bean>
</beans>

Xml declaration take precedence over annotation, so you can not use both.

But why do you want declare the components via annotation if you will not want to use DI? That makes no sense.

it is fixable and up to what you are prefer to declare components "Spring beans":

  1. use component-scan

  2. write it in XML using

also it is up to you to define relation between components:

  1. using @Autowired

  2. using or in xml

the 2 action are different, it is like initialize bean and setting reference of bean in property of another bean, the only point to use "component-scan" with "@Autowired" is that @Autowired is using type and "component-scan" is not forcing the id or name of bean generated, so it is better to use both together but if you want to use scan without autowiring you have to take care about not using 2 component with same class name, also to care about any typo in writing the reference names.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM