【问题标题】:@Autowired and @Service working from controller but not from a different package@Autowired 和 @Service 从控制器工作,但不是来自不同的包
【发布时间】:2012-10-12 15:19:16
【问题描述】:

我需要帮助来理解 @Autowired@Service 背后的概念。我有一个用@Service 定义的DAO 和用@Autowired 定义的控制器,一切似乎都很好,但是,我在不同的类中使用相同的@Autowired 然后它不起作用。

例子:

服务

@Service
public class MyService {
    private JdbcTemplate jdbcTemplate;

    @Autowired
    public void setDataSource (DataSource myDataSource) {
        this.jdbcTemplate = new JdbcTemplate(myDataSource);
    } 

    public void testUpdate(){
            jdbcTemplate.update("some query");
    }
}

控制器

package com.springtest.mywork.controller;

@Controller
@RequestMapping(value = "/test.html")
public class MyController
{
  @Autowired
  MyService myService;

  @RequestMapping(method = RequestMethod.GET)
  public String test(Model model)
  {
    systemsService.testUpdate();
    return "view/test";
  }
}

以上都可以正常工作。但是,如果我想在 POJO 中使用MyService,那么它就是行不通的。示例:

package com.springtest.mywork.pojos;
public class MyPojo {

    @Autowired
    MyService myService;

    public void testFromPojo () {
        myService.someDataAccessMethod(); //myService is still null
    }
}

弹簧配置:

<beans>
    <mvc:annotation-driven />
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <context:component-scan base-package="com.springtest.mywork" />
    <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/mydb" />
        <property name="username" value="hello" />
        <property name="password" value="what" />
    </bean>

    <bean name="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
        <constructor-arg ref="dataSource"/>
    </bean>
 </beans>

【问题讨论】:

  • MyPojo 是否被 Spring 实例化了?
  • 我没有为 config.xml 中的MyController 做任何事情,所以我也没有为MyPojo 做任何事情。我该怎么办?
  • 你能发布你的 Spring 配置吗?
  • 已更新,底部添加了 spring 配置

标签: java spring-mvc spring-3 autowired


【解决方案1】:

这是因为你的POJO类没有被spring容器管理。

@Autowire 注解只适用于那些由spring管理的对象(即由spring容器创建的)。

在您的情况下,服务和控制器对象由 spring 管理,但您的 POJO 类不由 spring 管理,这就是 @Autowire 没有产生您预期的行为的原因。

我注意到的另一个问题是,当 spring 专门为此目的创建了 @Repository 注释时,您在 DAO 层中使用了 @Service 注释。

另外,不允许 spring 管理 POJO 类也是不可取的,因为通常它将是必须在容器外部创建的数据存储元素。

【讨论】:

【解决方案2】:

使用类路径扫描时,您必须与 Spring 沟通要管理哪些类。这是使用@Service 注释及其关系(@Controller@Repository 等)完成的。

如果你选择来注释你的bean,你必须在你的配置中明确声明它,就像你对dataSourcejdbcTemplate所做的那样。

注释你的类意味着只有包中的那些类是由 Spring 管理的;这允许您扫描一个包,而无需管理该包中的所有类。

【讨论】:

  • 所以我应该用@Service@Repository@Controller 来注释我的POJO?
  • 我宁愿添加注释而不是在 xml 中定义它
  • “注释类可以防止包中的每个类都由 Spring 管理;这通常是不可取的。”真的吗?所以在一个包中只能注释一个类?
  • @Service 是最不具体的,所以我会使用它。
  • @birdy 我的意思是,通过注释,您可以选择要管理的类。
【解决方案3】:

将其包含在 applicationContext.xml 文件中

<context:annotation-config />

【讨论】:

    【解决方案4】:

    您可以实现它以在您的 POJO 类中使用 spring 管理的 bean。

    http://www.javacodegeeks.com/2015/03/using-spring-managed-bean-in-non-managed-object.html

    【讨论】:

    • 请避免仅链接答案。
    【解决方案5】:

    检查配置文件中的上下文组件扫描

    <context:component-scan base-package="<your_package>" />
    

    【讨论】:

    • 我已经检查过了。它正在扫描所有的包。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    • 2013-12-11
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多