如果不自动完成,如何手动注入弹簧注射

问题描述 投票:1回答:2

我的春天依赖项工作正常,但有一堂课

CustomUserDetaisls我需要调用Autowired依赖项

@Autowired Private UserDAO userDAO

与用户名和密码匹配

但是我的弹簧注射不起作用,因为这个类实现了userDetailsSerivce。但是,如果我删除工具,注入工作。

我已经提交了问题,问为什么在this question,但没有人给我答案,所以我决定使用DAO与新的运算符

private UserDAO userDAO = new UserDAO();

userDAO反过来依赖于会话工厂,这是一个春天豆。

然后我再次决定从java代码获取sessionfactory,而不是使用以下代码

SessionFactory sessionFactory = new AnnotationConfiguration()
        .configure("com/vaannila/service/hibernate.cfg.xml")
        .buildSessionFactory();

但是我又在hibernate-context中有几个bean,比如数据源,属性文件,我发现很难重写所有的东西。

有没有办法我可以手动注入userDAO,以便所有相关的弹簧注入像sessionFactories一样

java hibernate spring
2个回答
5
投票

如果您有权访问spring上下文,则可以检索一个AutowireCapableBeanFactory,然后可以在任何bean上使用它,如下所示:

ApplicationContext springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContextEvent.getServletContext());
AutowireCapableBeanFactory factory = springContext.get(AutowireCapableBeanFactory.class);

// this would instantiate and autowire a bean:
UserDAO userDAO = factory.createBean(UserDAO.class);

// this will autowire an already existing bean:
UserDAO manualUserDAO = new UserDAO();
factory.initializeBean(manualUserDAO, "beanNameIfNeeded"); 

但是,如果一个bean要求在它可以被使用之前自动装配,我更喜欢使用第一个机制并将构造函数标记为private / protected,以确保它不能通过'new'创建并强制它通过像上面这样的工厂。

更新11/27/17

我个人不想每次想要创建自动装配的实例时都使用工厂。特别是如果某个其他进程正在创建实例,例如从数据库反序列化等。

我最终创建了一个方面来自动处理自动装配。

首先,我创建了一个注释来标记我想要自动自动装配的类:

@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface AutowireAfterCreation {
}

然后我创建了一个方面,使用“后构造”点切割来进行自动装配。不幸的是,我无法弄清楚只有在“最后一个”构造函数完成后才调用的切入点,但它似乎并没有多次伤害自动装配,至少在我的情况下。

public aspect AutowiringAfterCreation {

    @Autowired
    private AutowireCapableBeanFactory beanFactory;

    /**
     * After construction, autowire the instance.
     * @param o Newly created object to be autowired.
     */
    after(Object o) returning : target(o) && initialization((@AutowireAfterCreation *).new(..)) {
        // this aspect will actually autowire the instance multiple times if the class is part of an inheritance
        // Hierarchy.  This is not optimal, but it should not hurt anything to autowire more than once.
        // FUTURE: modify the aspect so it only runs once, regardless of how many constructor calls are necessary.
        beanFactory.autowireBeanProperties(o, AutowireCapableBeanFactory.AUTOWIRE_NO, false);
        beanFactory.initializeBean(o, "unused");
    }   
}

然后我不得不告诉Spring有关方面的问题,以便将factoryBean自动装入方面本身:

<bean class="AutowiringOnDemand" factory-method="aspectOf"/>

现在我可以创建任何实例并通过附加注释自动自动装配:

@AutowireAfterCreation
public class TestEntity {

    @Value("${some.config.value}")
    private String value;

    @Autowired
    private TestRepository repository;

}

最后,您所要做的就是创建一个实例,并在构造函数完成后自动自动装配:

TestEntity entity = new TestEntity();

更新1/2/2018

ApplicationContext接口已更改,并且get()已被删除,但您仍然可以使用第一种机制,但您需要调用getAutowireCapableBeanFactory()。

因此,此答案顶部示例中的前两行现在看起来像:

ApplicationContext springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContextEvent.getServletContext());
AutowireCapableBeanFactory factory = springContext.getAutowireCapableBeanFactory();

2
投票

你可以看一下spring java配置。 http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java

在下面的示例中,UserDAO的所有依赖项将由spring自动设置。它应该是这样的:

@Configuration
@PropertySource("classpath:configuration.properties")
public class ApplicationConfig {
    @Bean
    public UserDAO userDAO() {
    return new UserDAO();
    }
    @Bean
    public CustomUserDetails customUserDetails (UserDAO userDAO) {
       CustomUserDetails customUserDetails = new CustomUserDetails ();
       customUserDetails.setUserDAO(userDAO());
       return customUserDetails;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.