Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.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
Java 在非组件对象上使用Spring@Value_Java_Spring_Spring Mvc - Fatal编程技术网

Java 在非组件对象上使用Spring@Value

Java 在非组件对象上使用Spring@Value,java,spring,spring-mvc,Java,Spring,Spring Mvc,我遇到了一个我不知道如何解决的问题。我使用SpringBoot创建了RESTfulAPI,并且我正在实现DTO域实体模式,所以在这个特殊情况下,我有这个控制器的方法 @RequestMapping(method = RequestMethod.POST) @ResponseBody public ResponseEntity<UserResponseDTO> createUser(@RequestBody UserRequestDTO data) { UserDomain u

我遇到了一个我不知道如何解决的问题。我使用SpringBoot创建了RESTfulAPI,并且我正在实现DTO域实体模式,所以在这个特殊情况下,我有这个控制器的方法

@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<UserResponseDTO> createUser(@RequestBody UserRequestDTO data) {
    UserDomain user = this.mapper.map(data, UserDomain.class);
    UserDomain createdUser = this.service.createUser(user);
    UserResponseDTO createdUserDTO = this.mapper.map(createdUser, UserResponseDTO.class);
    return new ResponseEntity<UserResponseDTO>(createdUserDTO, HttpStatus.CREATED);
}

public class UserDomain {

    private Long id;

    private Date createdDate;

    private Date updatedDate;

    private String username;

    private String password;

    @Value("${default.user.enabled:true}") // I have default-values.properties being loaded in another configuration file
    private Boolean enabled;
}

如果您的映射程序有一个方法,该方法采用已准备好的实例而不是
,那么您可以添加原型作用域
用户域
bean,并从控制器方法调用
上下文.getBean()

控制器


否则,您可以使用和AspectJ编译时编织。但是您必须决定是否值得在项目中引入编织,因为您有其他方法来处理这种情况

pom.xml

弹簧配置

相同

请参阅Spring文档以了解有关的更多信息


编辑 关于你的编辑

请注意,您在那里使用。这意味着
UserDomain
实例必须由Spring容器管理。容器不知道在其外部创建的实例,因此不会为此类实例解析(完全相同),例如
UserDomain UserDomain=new UserDomain()
UserDomain.class.newInstance()
。因此,您仍然需要向上下文添加一个原型范围的
UserDomain
bean。实际上,这意味着所提出的方法与关联的方法类似,只是它将您的
UserDomain
与Spring绑定在一起。因此,这是不好的

使用或不将您的域对象绑定到Spring,仍然可以设计出更好的解决方案

ApplicationContextProvider.java

弹簧配置


然而,我不喜欢这种方法的额外复杂性和草率性。我认为这一点都不合理。

你没有服务层吗?首选项、参数、默认值等应该注入到服务类中,这些服务类是集中业务逻辑的,应该由Spring管理

如果没有
用户服务
,则将默认值加载到控制器中

我只是注意到从DTO到domain类的转换正在控制器中进行

定义

@Value("${default.user.enabled:true}")  
private Boolean defaultUserEnabled;
在控制器内部,然后

if (user.isEnabled() == null)
    user.setEnabled(defaultUserEnabled);

但是,正如我已经说过的,默认值的声明和设置都属于Spring托管服务类。

可能的重复项实际上不是我想要的。我知道我可以连接环境并获取属性,但我想在这里通过@Value annotations.Fine来实现。请看我的答案。非常好的答案!还有一件事。您认为使用环境在UserDomain构造函数中获取属性(例如)更好吗?或者你更愿意像你在这个答案中解释的那样去做?谢谢我认为解决这种情况的最佳方法是使用prototype作用域
UserDomain
bean。这样,您的域代码就不会绑定到Spring,也不会有与编织相关的额外开销(甚至编译时)?这将提高性能,因为我不必将所有对象层实例(dto域实体)都创建为Spring Bean,这几乎是我一直在寻找的。谢谢我不认为这是一个优雅的解决方案。无论如何谢谢你!从概念上讲,从架构的角度来看,这是一个不错的解决方案。但是,
UserService
不在
UserRequestDto
上运行,并且不应该进行转换
defaultUserEnabled
在逻辑上也不属于控制器。因此,在我个人看来,在这种情况下,出于转换目的,可能需要在控制器和服务之间引入一个附加层。
@Configuration
public class Config {

    @Bean
    public static PropertySourcesPlaceholderConfigurer properties() {
        PropertySourcesPlaceholderConfigurer propConfigurer = new PropertySourcesPlaceholderConfigurer();
        propConfigurer.setLocation(new ClassPathResource("application.properties"));
        return propConfigurer;
    }

    @Bean
    @Scope("prototype")
    public UserDomain userDomain() {
        return new UserDomain();
    }

    ...
}
...

<!-- additional dependencies -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>4.2.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.8.6</version>
</dependency>

...

<!-- enable compile-time weaving with aspectj-maven-plugin -->
<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.7</version>
            <configuration>
                <complianceLevel>1.8</complianceLevel>
                <encoding>UTF-8</encoding>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-aspects</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
                <Xlint>warning</Xlint>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

...
@Configurable
public class UserDomain {

    private Long id;

    private Date createdDate;

    private Date updatedDate;

    private String username;

    private String password;

    @Value("${default.user.enabled:true}")
    private Boolean enabled;

    ...
}
@Configuration
@EnableSpringConfigured
public class Config {

    @Bean
    public static PropertySourcesPlaceholderConfigurer properties() {
        PropertySourcesPlaceholderConfigurer propConfigurer = new PropertySourcesPlaceholderConfigurer();
        propConfigurer.setLocation(new ClassPathResource("application.properties"));
        return propConfigurer;
    }

    ...
}
public class ApplicationContextProvider implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    public static <T> T getEnvironmentProperty(String key, Class<T> targetClass, T defaultValue) {
        if (key == null || targetClass == null) {
            throw new NullPointerException();
        }

        T value = null;
        if (applicationContext != null) {
            System.out.println(applicationContext.getEnvironment().getProperty(key));
            value = applicationContext.getEnvironment().getProperty(key, targetClass, defaultValue);
        }
        return value;
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
}
public class UserDomain {

    private Boolean enabled;

    public UserDomain() {
         this.enabled = ApplicationContextProvider.getEnvironmentProperty("default.user.enabled", Boolean.class, false);
    }

    ...
}
@Configuration
@PropertySource("classpath:application.properties")
public class Config {

    @Bean
    public ApplicationContextProvider applicationContextProvider() {
        return new ApplicationContextProvider();
    }

    ...
}
@Value("${default.user.enabled:true}")  
private Boolean defaultUserEnabled;
if (user.isEnabled() == null)
    user.setEnabled(defaultUserEnabled);