-1

使用组件扫描而不在弹簧上使用自动装配是否有意义?

我喜欢在控制器的 MVC 环境中进行组件扫描的想法,我什至喜欢避免在 xml 上声明所有 DAO、服务……。

但是我不是自动装配的忠实拥护者,所以,是否仍然可以使用 xml 配置文件手动注入所需的 bean,或者这只是无意义的?

更新:使用 @Autowired 而不是通过 XML 显式声明的优势是什么(请不要提供“较少的 xml 配置”作为优势)

4

3 回答 3

2

我会

  • 添加@Component到实现类,以便为每个实现类创建一个 bean
  • 不关联@Autowired/@Resource与其他类中与这些实现相对应的成员声明,​​以便Spring不能autowire它们。
  • 定义需要这些组件 bean 的 bean,在 XML 中使用<bean>节点和<property>元素通过 setter<constructor-arg>注入它们或通过构造函数注入它们。

例子:

界面:

package com.krovi.compscan;

public interface MyInterface
{
    void method();
}

实现声明为 Spring DI 框架的组件,以为此创建一个 bean:

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");
    }
}

一个典型的客户端,他将使用基于组件的 bean,但通过配置文件,通过构造函数显式注入。

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();
    }
}

另一个使用基于组件的bean但使用setter通过配置文件显式注入的典型客户端:

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();
    }
}

豆配置文件:

<?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>
于 2013-04-20T03:21:16.450 回答
1

xml 声明优先于注释,因此您不能同时使用两者。

但是,如果您不想使用 DI,为什么还要通过注解来声明组件呢?这是没有意义的。

于 2013-04-20T02:48:37.757 回答
0

它是可修复的,并且取决于您更喜欢声明组件“Spring bean”:

  1. 使用组件扫描

  2. 使用 XML 编写它

您还可以定义组件之间的关系:

  1. 使用@Autowired

  2. 在 xml 中使用或

2个动作是不同的,就像在另一个bean的属性中初始化bean和设置bean的引用一样,使用“组件扫描”和“@Autowired”的唯一一点是@Autowired正在使用类型和“组件扫描”不强制生成 bean 的 id 或名称,因此最好将两者一起使用,但如果您想在不自动装配的情况下使用扫描,则必须注意不要使用具有相同类名的 2 个组件,还要注意任何错字编写参考名称。

于 2013-04-20T09:29:16.660 回答