java Spring - 使用 @Configurable 和 @Value 注释使用 new 运算符创建对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15106163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 18:29:39  来源:igfitidea点击:

Spring - creating objects with new operator using @Configurable & @Value annotations

javaspringpropertiesdependency-injectionaspectj

提问by NightWolf

Is it possible to use @Configurable on a class that's weaved using AspectJ and get Spring to load in values on fields/methods which are annotated with @Value?

是否可以在使用 AspectJ 编织的类上使用 @Configurable 并让 Spring 加载使用 @Value 注释的字段/方法的值?

I know its possible with @Autowired and @Resource etc... Are there any others.

我知道@Autowired 和@Resource 等是可能的......还有其他的吗?

e.g.

例如

@Configurable
public Class MyObj{
 @Value("$(my.prop)")
 private String aField;

 public String getAField(){
   return aField;
 }
}

And then have something like

然后有类似的东西

public aMethodSomewhereElse(){
   MyObj obj = new MyObj()
   assertNotNull(obj.getAField());
}

Are there any alternatives to being able to create MyObjwith the newoperator and still get spring to handle the annotations?

除了能够MyObjnew操作员一起创建并仍然让 spring 处理注释之外,还有其他选择吗?

--EDIT:--

- 编辑: -

It IS possible to do this using newwhen using @Autowired, have a look at some Hibernate and JPA stuff with Spring and AOP... I've used this in the past to do some profiling of Java code. But I really want to use SPEL and @Value before I mock up a full example I was hoping to find the answer here. FYI - if you don't belive me the Spring Manual even says it is possible to do this, what I want to know is if its possible to use @Valueannotations in the same scope...

new使用 @Autowired 时可以做到这一点,用 Spring 和 AOP 看看一些 Hibernate 和 JPA 的东西......我过去曾用它来对 Java 代码进行一些分析。但我真的很想在模拟一个完整的例子之前使用 SPEL 和 @Value,我希望在这里找到答案。仅供参考 - 如果您不相信我,Spring 手册甚至说可以这样做,我想知道是否可以在同一范围内使用@Value注释......

The Spring container instantiates and configures beans defined in your application context. It is also possible to ask a bean factory to configure a pre-existing object given the name of a bean definition containing the configuration to be applied. The spring-aspects.jar contains an annotation-driven aspect that exploits this capability to allow dependency injection of anyobject.

Spring 容器实例化并配置在您的应用程序上下文中定义的 bean。给定包含要应用的配置的 bean 定义的名称,也可以要求 bean 工厂配置一个预先存在的对象。spring-aspects.jar 包含一个注解驱动的方面,它利用这个能力来允许任何对象的依赖注入。

And...

和...

Using the annotation on its own does nothing of course. It is the AnnotationBeanConfigurerAspect in spring-aspects.jar that acts on the presence of the annotation. In essence the aspect says "after returning from the initialization of a new object of a type annotated with @Configurable, configure the newly created object using Spring in accordance with the properties of the annotation". In this context, initialization refers to newly instantiated objects (e.g., objects instantiated with the 'new' operator) as well as to Serializable objects that are undergoing deserialization (e.g., via readResolve()).

当然,单独使用注释没有任何作用。spring-aspects.jar 中的 AnnotationBeanConfigurerAspect 作用于注解的存在。本质上,该方面表示“从使用@Configurable 注释的类型的新对象的初始化返回后,根据注释的属性使用 Spring 配置新创建的对象”。在此上下文中,初始化指的是新实例化的对象(例如,使用“new”运算符实例化的对象)以及正在进行反序列化的可序列化对象(例如,通过 readResolve())。

http://static.springsource.org/spring/docs/3.0.0.RC2/reference/html/ch07s08.html

http://static.springsource.org/spring/docs/3.0.0.RC2/reference/html/ch07s08.html

Cheers.

干杯。

采纳答案by Biju Kunjummen

You are absolutely right - @Autowiredfields will be wired in an @Configurableannotated class even outside of a Spring container, assuming that you have a AspectJ infrastructure in place.

您是绝对正确的 -假设您有一个 AspectJ 基础设施,即使在 Spring 容器之外,@Autowired字段也将连接到带@Configurable注释的类中。

You have noted a good catch though, @Valuefields are processed by a Spring bean post processor(AutowiredAnnotationBeanPostProcessor), which resolves the @Valueannotated fields. It does not act on objects instantiated outside of the container though - so in short, the @Autowired fields should get wired in, but @Valueproperties will not.

您已经注意到一个很好的问题,@Value字段由 Spring bean 后处理器 (AutowiredAnnotationBeanPostProcessor) 处理,它解析带@Value注释的字段。不过,它不会作用于在容器外部实例化的对象 - 所以简而言之,@Autowired 字段应该被连接,但@Value属性不会。

回答by DominikM

Doing

正在做

MyObj obj = new MyObj()

means that obj is not managed by spring, so it will not do autowiring. Only way to do that is to obtain instance from an application context. For example:

意味着 obj 不是由 spring 管理的,所以它不会自动装配。唯一的方法是从应用程序上下文中获取实例。例如:

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyObj obj = context.getBean("myBean");

回答by Arun P Johny

I don't think it is possible to use newoperator and ask spring to autowire properties. I think 1 way to solve this is to get a static reference to applicationContextand create a prototype scoped bean.

我认为不可能使用new运算符并要求 spring 自动装配属性。我认为解决这个问题的一种方法是获取静态引用applicationContext并创建一个原型作用域 bean。

@Component
public class ApplicationContextLocator {
    private static ApplicationContext applicationContext;

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public ApplicationContextLocator() {
        super();
    }

    @Autowired
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextLocator.applicationContext = applicationContext;
    }

}

@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Component
public class MyObj {
    .....
}

public aMethodSomewhereElse(){
   MyObj obj = ApplicationContextLocator.getApplicationContext().getBean(MyObj.class)
   assertNotNull(obj.getAField());
}