如何向数据对象注入@value?

eiee3dmh  于 2021-07-13  发布在  Java
关注(0)|答案(3)|浏览(276)

我有一个数据对象(仅含getters\setter)需要知道spring概要文件,即。

@Value("${spring.profiles.active}")
private String profile;

我在其中一个检查概要文件的“set”方法中添加了一个逻辑,即。

public void setItem(Item msg) {
    if (environmentProperties.isDevMode()) {
        this.msg= msg;
    }
}

因为这个类通常是在外部封送\unmarshall的,所以当然没有填充@value-因为我没有使用spring autowire来创建类示例。。。我尝试将该类定义为component,并自动连接到一个外部类,该类包含profile@value,但在我使用Spring3.2时,它不起作用,因为没有xml定义。
有什么建议吗?
b、 t.w.数据对象通常被 Package 在一个异常类中-所以当它被创建时,概要文件也应该被数据对象知道。。。
谢谢!
编辑时间:
使用applicationcontextaware不起作用-我得到null“setapplicationcontext”方法从未被调用。
另外,尝试直接获取上下文也不起作用-使用“applicationcontext ctx=contextloader.getcurrentwebapplicationcontext();”时改为获取null
修复:我最终找到了一个如何从外部类静态访问上下文的示例:

@Configuration
public class ApplicationContextContainer implements ApplicationContextAware {

    private static ApplicationContext CONTEXT;

    /**
     * This method is called from within the ApplicationContext once it is
     * done starting up, it will stick a reference to itself into this bean.
     *
     * @param context a reference to the ApplicationContext.
     */
    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        CONTEXT = context;
    }

    /**
     * This is about the same as context.getBean("beanName"), except it has its
     * own static handle to the Spring context, so calling this method statically
     * will give access to the beans by name in the Spring application context.
     * As in the context.getBean("beanName") call, the caller must cast to the
     * appropriate target class. If the bean does not exist, then a Runtime error
     * will be thrown.
     *
     * @param beanName the name of the bean to get.
     * @return an Object reference to the named bean.
     */
    public static Object getBean(String beanName) {
        return CONTEXT.getBean(beanName);
    }
krcsximq

krcsximq1#

如果我理解正确的话,您希望注入到不是由spring管理的对象中,而是由一些其他代码创建的,这些代码在内部调用new并返回对象,例如序列化框架。
要注入非托管对象,您需要配置加载时或编译时编织。加载时编织需要一个代理参数和lib当您启动vm时,一些容器可能会为您这样做。
编译时编织需要使用aspectj编译器。
下面是使用maven和spring boot的完整示例:
e、 g.运行时使用:

mvn spring-boot:run -Drun.arguments="--spring.profiles.active=dev"

演示应用程序.java:

package com.example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.aspectj.EnableSpringConfigured;
import org.springframework.stereotype.Component;

@SpringBootApplication
public class DemoApplication {
    @EnableSpringConfigured
    @ComponentScan("com.example")
    public static class AppConfiguration {
        @Value("${spring.profiles.active}")
        String profile;

        @Bean
        public String profile() {
            return profile;
        }
    }

    @Configurable
    public static class SomePojo {
        @Autowired
        private String profile;

        public void print() {
            System.out.println(this + "\t" + profile);
        }
    }

    @Component
    public static class Runner {
        public void run() {
            new SomePojo().print();
            new SomePojo().print();
        }
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args).getBean(Runner.class).run();
    }

}

pom.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.3.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.8</version>
                <configuration>
                    <complianceLevel>1.8</complianceLevel>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                </configuration>
                <executions>
                    <execution>
                        <id>compile</id>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
zqdjd7g9

zqdjd7g92#

根据您的描述,您试图将属性注入到pojo中,pojo用于编组。使用这种结构,您可以使用基于静态/任何其他复杂解决方案寻找不同的解决方法。
我建议将用作pojo的bean与依赖于属性值的逻辑分开。您可以将该逻辑提取到beanservice(可以将其放置到spring上下文中)并在该级别上处理它,以便将服务层和数据层之间的责任分离开来。

fwzugrvs

fwzugrvs3#

你做错了。您的代码不需要知道配置文件。在您的示例中,创建一个消息接口,以及该接口的许多bean实现,每个概要文件一个,每个都包含该概要文件的适当消息,并将每个实现分配给一个概要文件,以便为该概要文件示例化bean,并将示例注入到需要该消息的类中。
所以,

public interface Message { String getMessage(); }

@Profile("dev") @Component
public class DevMessage implements Message { 
  public String getMessage() { return "this is the dev message"; }
}

@Profile("prod") @Component
public class ProdMessage implements Message {
  public String getMessage() { return "this is the production message"; }
}

如果您喜欢在@configuration类中描述bean,那么可以使用@profile标记整个配置,并具有多个配置。
如果将消息示例注入到类中,则可以对其调用getmessage()。概要文件将确保您拥有适合您的环境的适当实现。
编辑:我刚刚重读了你的问题,意识到我错了。实体对象存储在应用程序外部,并通过一些代码/框架示例化。这些不是spring组件,因此不能使用spring方法进行依赖注入。在这种情况下,不要对它们使用spring——它不起作用,不必起作用,也不应该起作用。如果您没有通过spring示例化对象,那么它应该与spring无关。我不知道你的问题域,但自从spring发明以来,我就一直在使用它,从来没有这样做过。

相关问题