Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SpringJavaConfig中,如何初始化依赖于@Service的@Bean_Java_Spring_Hibernate_Spring Java Config - Fatal编程技术网

在SpringJavaConfig中,如何初始化依赖于@Service的@Bean

在SpringJavaConfig中,如何初始化依赖于@Service的@Bean,java,spring,hibernate,spring-java-config,Java,Spring,Hibernate,Spring Java Config,我已经将一个基于Spring4.0的项目从xml转换为javaconfig 初始化时,我的一个bean需要访问Hibernate,通过Spring@Service(buildingService)从数据库获取一些配置数据。bean初始化如下所示: @Bean @DependsOn({ "transactionManager", "webSocketHandler", "buildingService" }) Smarty smarty() { Smarty bean = new Smar

我已经将一个基于Spring4.0的项目从xml转换为javaconfig

初始化时,我的一个bean需要访问Hibernate,通过Spring@Service(
buildingService
)从数据库获取一些配置数据。bean初始化如下所示:

@Bean
@DependsOn({ "transactionManager", "webSocketHandler", "buildingService" })
Smarty smarty() {
    Smarty bean = new Smarty();
    bean.init(); // I also tried @Bean(initMethod = "init") with no difference
    return bean;
}
@Service("buildingService")
@Transactional
public class BuildingService {

...

    public List<Building> getAll() {
        final Session session = sessionFactory.getCurrentSession();
        final Query query = session.createQuery("from Building order by name");
        return query.list();
    }

...

}
问题在于,在
bean.init()
中,服务被访问,这会导致
NullPointerException
失败

我将
buildingService
添加到
@DependsOn
中,但没有任何帮助

可能是
@Service
-注释类在
@Bean
之后处理

我可以自己预先初始化
@Service
-注释类吗

编辑1

感谢所有的反馈

我需要补充一些细节:

buildingService不是一个
@Bean
,它是一个
@Service
,看起来是这样的:

@Bean
@DependsOn({ "transactionManager", "webSocketHandler", "buildingService" })
Smarty smarty() {
    Smarty bean = new Smarty();
    bean.init(); // I also tried @Bean(initMethod = "init") with no difference
    return bean;
}
@Service("buildingService")
@Transactional
public class BuildingService {

...

    public List<Building> getAll() {
        final Session session = sessionFactory.getCurrentSession();
        final Query query = session.createQuery("from Building order by name");
        return query.list();
    }

...

}
我尝试用
@PostConstruct
注释
Smarty.init()
,但这并没有改变任何事情


请注意,
Smarty.init()
做的第一件事是调用
buildingService.getAll()

@Sevice
通过组件扫描自动发现并初始化带注释的bean,以便在Spring配置上启用此使用
@ComponentScan

@组件扫描

配置组件扫描指令以与
@Configuration
类一起使用

@Bean
用于手动创建Bean,无需使用特殊注释,如
@Service
或组件扫描

@Bean

指示方法生成要由Spring容器管理的bean。(...) 通常,@Bean方法在@Configuration类中声明。在这种情况下,bean方法可以通过直接调用同一类中的其他@bean方法来引用它们


上下文配置

@Autowired
EntityManager entityManager; //needs to access Hibernate

@Bean
Smarty smarty() {
   return = new Smarty(entityManager);
}
还有你的
Smarty
bean

public Smarty {

   final EntityManager entityManager;

   public Smarty(EntityManager entityManager){
      this.entityManager = entityManager;
   }
}

您对bean的生命周期感到困惑。Spring必须先创建bean,然后才能注入任何内容。在
@Bean
方法中,您已经创建了Bean

Smarty bean = new Smarty(); 
然后立即调用它的一个方法

bean.init();
这似乎取决于注入的磁场

这两个电话之间没有任何区别。你认为春天会怎么做

相反,您可以使用
@PostConstruct
注释
init()
方法。Spring初始化bean后,即当
@bean
方法返回并注入所有对象的注入目标时,它将自动调用该方法


这里不需要
@DependsOn

您不需要
@DependsOn
注释,因为Smarty bean对BuildingService有(或应该有)直接依赖关系。有关何时使用它的更多信息,请参阅javadoc

以下示例演示如何解决问题:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SmartyTest.TestConfig.class)
public class SmartyTest {

@Autowired
Smarty1 smarty1;

@Autowired
Smarty2 smarty2;

@Test
public void testSmarty() throws Exception {
}

@Configuration
static class TestConfig {

    @Bean
    public BuildingService buildingService() {
        return new BuildingService();
    }

    @Bean
    public Smarty1 smarty1(BuildingService buildingService) {
        Smarty1 smarty = new Smarty1(buildingService);
        smarty.init();
        return smarty; // manually inject dependencies & handle initialisation
    }

    @Bean
    public Smarty2 smarty2() {
        // injecting the building service & initialising the component is handled by spring
        // by using @Autowired & @PostConstruct(-> alternative to @Bean(initMethod="init"))
        return new Smarty2();
    }
}


static class BuildingService {
    public void buildSomething() {
        System.out.println("BuildingService: I am building something!");
    }
}


static class Smarty1 {
    BuildingService buildingService;

    Smarty1(BuildingService buildingService) {
        this.buildingService = buildingService;
    }

    public void init() {
        System.out.println("Smarty 1: initialising ...");
        buildingService.buildSomething();
    }
}

static class Smarty2 {
    @Autowired
    BuildingService buildingService;

    @PostConstruct
    public void init() {
        System.out.println("Smarty 2: initialising ...");
        buildingService.buildSomething();
    }
}
}