没有bean声明就不会调用@PostConstruct spring

时间:2016-03-29 14:32:09

标签: spring spring-mvc

为什么没有在applicationContext.xml

中放入bean而不调用post构造

这是我的类,其中包含@PostConstruct注释。

private void readTxt(File file){
        File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/dataFile.txt");
        StringBuilder text = new StringBuilder();
        try{
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line;
            while ((line = br.readLine()) != null) { 
                text.append(line);
                text.append('\n');
            }
            br.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String data = "";
        StringTokenizer st = new StringTokenizer(text,"-");
        while(st.hasMoreTokens()){
            // you can set values to the column as much as you have
            ContentValues contentValues = new ContentValues();
            contentValues.put("COLUMN_NAME1", st.nextToken());
            contentValues.put("COLUMN_NAME2", st.nextToken());
            contentValues.put("COLUMN_NAME3", st.nextToken());
            database.insert(TABLA_PRINCIPAL, null, contentValues); // se inserta en la BD
            Toast.makeText(getBaseContext(), "Datos agregados", Toast.LENGTH_LONG).show(); // muestra mensaje de inserccion satisfactorio
        }
    }

以下是我的applicationContext.xml

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

看起来很简单,但如果没有取消注释bean声明它就无法工作。

5 个答案:

答案 0 :(得分:4)

在Spring环境中,初始化回调方法(由@PostConstruct注释的方法)仅在spring-managed-beans上有意义。要使PropertyLoader类的实例受管理,您必须执行以下操作之一:

  1. 在上下文配置中明确注册您的课程(如您所做)
    <bean id="proeprtyLoader" class="org.stalwartz.config.PropertyLoader"></bean>
  2. 让组件扫描完成工作(就像你几乎一样),但类必须由@Component, @Repository, @Service, @Controller之一注释。
  3. 来自Spring documentation的注释:使用<context:component-scan>隐式启用<context:annotation-config>的功能。使用<context:annotation-config>时,通常无需包含<context:component-scan>元素。

答案 1 :(得分:1)

Singleton是范围注释。它可以用来声明“单身”&#39;特定bean的范围,但不实例化它。请参阅this文章。

如果要将类实例化为单例,可以尝试Spring Service注释。

@Service
public class PropertyLoader {

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

此外,您可以使用component-scan替换annotation-config标记。关于注释配置和组件扫描标签的差异,这是一个很好的article

答案 2 :(得分:0)

因为将bean放在applicationContext.xml中,所以要将bean添加到Spring容器中,该容器具有此批注的拦截器。当Spring注入bean时,它会在其他人之间检查@PostConstruct注释。

当您调用简单的新PropertyLoader()时,JVM将不会搜索@PostConstruct注释。

来自@PostConstruct注释的文档:

PostConstruct注释用于需要执行的方法 在完成依赖注入以执行任何初始化之后。这个 必须在类投入使用之前调用方法。这个 必须支持所有支持依赖的类的注释 注射。用PostConstruct注释的方法必须调用 如果该类没有请求注入任何资源。

答案 3 :(得分:0)

你正在使用来自@Singleton包的javax.inject,它不会被spring容器选为bean。将其更改为:

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范围

一起使用

答案 4 :(得分:0)

默认情况下,bean singleton作用于Spring@PostConstruct通常用于service bean,服务bean必须作用于prototype,因为您需要为该特定班级设置多个对象,Spring将为您提供singleton个实例。

同样通过这个春天会多次尝试找到这个service bean并最终抛出异常:

  

java.lang.NoClassDefFoundError:无法初始化类org.springframework.beans.factory.BeanCreationException

所以在注释方式中尝试这样:

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

现在每件事都很好,并为你工作。