Spring MVC @PostConstruct spring在没有bean声明的情况下无法调用

ao218c7q  于 2022-12-19  发布在  Spring
关注(0)|答案(6)|浏览(257)

为什么不将bean放入applicationContext.xml中就不能调用post构造
下面是我的类,其中包含@PostConstruct注解。

package org.stalwartz.config;

import javax.annotation.PostConstruct;
import javax.inject.Singleton;

@Singleton
public class PropertyLoader {

    @PostConstruct
    public void init() {
         System.out.println("PropertyLoader.init()");
    }
}

下面是我的应用程序上下文. xml

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr" xmlns:tx="http://www.springframework.org/schema/tx"
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.xsd 
 http://www.springframework.org/schema/mvc 
 http://www.springframework.org/schema/mvc/spring-mvc.xsd 
 http://www.springframework.org/schema/tx 
 http://www.springframework.org/schema/tx/spring-tx.xsd 
 http://www.directwebremoting.org/schema/spring-dwr
 http://www.directwebremoting.org/schema/spring-dwr/spring-dwr-3.0.xsd">

<dwr:annotation-config />
<dwr:annotation-scan base-package="org.stalwartz" scanDataTransferObject="true" scanRemoteProxy="true" />
<dwr:url-mapping />

<!--  <bean id="proeprtyLoader" class="org.stalwartz.config.PropertyLoader"></bean>  -->

<dwr:controller id="dwrController" debug="false">
    <dwr:config-param name="activeReverseAjaxEnabled" value="true" />
</dwr:controller>

<context:annotation-config>
    <context:component-scan base-package="org.stalwartz" annotation-config="true"></context:component-scan>
</context:annotation-config>

<mvc:annotation-driven />
...
...
...
</beans>

看起来很简单,但是如果没有取消注解的bean声明,它就不能工作。

fdbelqdn

fdbelqdn1#

在Spring环境中,初始化回调方法(由@PostConstruct注解的方法)仅在spring-managed-beans上有意义。要使PropertyLoader类的示例成为托管的,必须执行以下操作之一:
1.在上下文配置中显式注册您的类(就像您所做的那样)
<bean id="proeprtyLoader" class="org.stalwartz.config.PropertyLoader"></bean>
1.让组件扫描来完成这项工作(就像您几乎要做的那样),但是类必须用@Component, @Repository, @Service, @Controller中的一个来注解。
Spring文档中的注解:使用<context:component-scan>隐式启用<context:annotation-config>的功能。使用<context:component-scan>时通常不需要包含<context:annotation-config>元素。

bprjcwpo

bprjcwpo2#

因为把bean放在applicationContext.xml中,你就在把bean添加到Spring容器中,Spring容器中有这个注解的拦截器。当Spring注入bean时,它会在其他bean之间检查@PostConstruct注解。
当您调用简单的new PropertyLoader()时,JVM不会搜索@PostConstruct注解。
来自@PostConstruct注解的文档:
PostConstruct注解用于需要在依赖项注入完成后执行以执行任何初始化的方法。必须在类投入使用前调用此方法。所有支持依赖项注入的类都必须支持此注解。即使类未请求注入任何资源,也必须调用用PostConstruct注解的方法。

yptwkmov

yptwkmov3#

Singleton是一个作用域注解。它可以用来为特定bean声明“singletone”作用域,但不能示例化它。请参阅this文章。
如果你想示例化你的类为单例,你可以尝试Spring Service注解。

@Service
public class PropertyLoader {

    @PostConstruct
    public void init() {
         System.out.println("PropertyLoader.init()");
    }
}

另外,你可以用component-scan替换annotation-config标记。

kse8i1jr

kse8i1jr4#

默认情况下,bean的作用域为Spring,而@PostConstruct通常用于service bean,服务bean的作用域必须为prototype,在这里,因为您需要多个对象用于该特定类,所以Spring将为您提供singleton示例。
此外,通过执行此操作,Spring将多次尝试查找此service bean,并最终引发以下异常:
java.lang.NoClassDefFoundError:无法初始化类组织。
因此,请尝试以下注解方式:

package org.stalwartz.config;

import javax.annotation.PostConstruct;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype") //you have to make it prototype explicitly
public class PropertyLoader {

    @PostConstruct
    public void init() {
         System.out.println("PropertyLoader.init()");
    }
}

现在一切都很好,为你工作得很好。

8yoxcaq7

8yoxcaq75#

您正在使用javax.inject包中的@Singleton,该包未作为bean被Spring容器拾取。请将其更改为:

package org.stalwartz.config;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
public class PropertyLoader {

    @PostConstruct
    public void init() {
        System.out.println("PropertyLoader.init()");
    }
}

Spring将自动检测PropertyLoader,并通过@Component注解将其作为bean包含在Spring容器中,此bean将具有singleton范围

vyu0f0g1

vyu0f0g16#

将此依赖项添加到pom.xml

<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>

相关问题