标签: spring-annotations

如何重构@Transactional方法来拆分非事务性部分

我有一个数据访问类,它作为独立的Java应用程序的一部分运行.它目前正在工作,这意味着定义了一个事务管理器,但我想重构该类以减少事务的范围,但如果我这样做,我得到org.hibernate.HibernateException:没有Hibernate Session绑定到线程,并且配置不允许在这里创建非事务性的,这意味着移动@Transactional会以某种方式阻止它被识别.

我的原始版本的重构方法是私有的,但我发现建议将其更改为public,因为在某些情况下注释不会被选中.

public class DoStuff {
    @Transactional
    public void originalMethod() {
        // do database stuff
        ...

        // do non-database stuff that is time consuming
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我想要做的是重构以下内容

public class DoStuff {
    public void originalMethod() {
        doDatabaseStuff()

        doNonDatabaseStuff()
    }

    @Transactional
    public void doDatabaseStuff() {
        ...
    }

    public void doNonDatabaseStuff() {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

java hibernate transactions spring-annotations hibernate-annotations

6
推荐指数
1
解决办法
1953
查看次数

如何从 OncePerRequestFilter 访问 Spring 控制器上的方法注释

在 OncePerRequestFilter (方法 doFilterInternal)中,我想访问有关最终将运行的控制器方法(最好是控制器本身)的信息。具体来说,我正在寻找该方法的注释。有没有办法从 doFilterInternal 方法访问它?

问题是,在无法访问方法本身的信息集的情况下,我们必须查看过滤器中的 url 来确定该方法是否属于这个特定类别。很快就会变得丑陋

if (url == "foo" || url == "bar" ... etc)
Run Code Online (Sandbox Code Playgroud)

理想情况下我们可以说

if(method.hasAnnotation(Blah.class)) //or however it would look

@Blah
public void controllerMethod(...){}
Run Code Online (Sandbox Code Playgroud)

在方法级别指定这一点会更简洁。有没有办法做到这一点,或者我缺少其他一些方法?

java spring annotations spring-annotations

6
推荐指数
0
解决办法
2029
查看次数

跨 Java 包自动装配 Spring Bean

我试图将我的项目分成三个模块:核心、管理员和用户,以便我可以通过核心共享公共代码。问题是,当我将所有东西都放在同一个包中时,我无法让 Spring 在不同的主包中提取自动装配的 bean。

在 com.mickeycorp.core 包中,我有我希望管理和用户模块使用的模型、服务等。在 com.mickeycorp.admin 中是我的 WebApplicationStarter(扩展 SpringBootServletInitializer),我有:

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
    ctx.register(SpringConfiguration.class);
    return application.sources(WebApplicationStarter.class);
}
Run Code Online (Sandbox Code Playgroud)

我认为应该选择我的配置类,其中包含以下内容:

@Configuration
@ComponentScan("com.mickeycorp")
public class SpringConfiguration {

}
Run Code Online (Sandbox Code Playgroud)

显然我误解了一些东西..我认为设置 ComponentScan 会使 Spring 扫描 com.mickeycorp 下的包以获取组件注释?

java spring spring-mvc spring-annotations

6
推荐指数
1
解决办法
4310
查看次数

如果spring中有多个配置文件,bean加载的顺序是什么?

我在 spring 应用程序中有三个配置文件。

@Configuration
public class FooConfig { ... }

@Configuration
public class BarConfig { ... }

@Configuration
public class FooBarConfig { ... }
Run Code Online (Sandbox Code Playgroud)

加载 bean 的顺序是什么?我可以beanFooConfigin 中使用定义的,BarConfig反之亦然吗?

编辑

这可以正常工作。但我怀疑它是否因为偶然而有效。这里有一个歧义,因为使用了不同的配置文件,并且解析它们的顺序对于正确加载 bean 很重要。

spring dependency-injection spring-mvc spring-annotations

6
推荐指数
1
解决办法
9838
查看次数

我们什么时候在 spring security 中使用 denyAll

我对为什么有人会使用@PreAuthorize("denyAll")一种方法感到有些困惑。根据 spring 安全文档,它始终评估为 false。

如果我们不打算允许访问特定的方法,那么保留这样的方法又有什么意义呢?为什么不注释掉呢?还是仍然可以从同一个类中访问它?

我试图了解在什么情况下会出现这样的要求。

java security spring spring-security spring-annotations

6
推荐指数
1
解决办法
2601
查看次数

@AutoConfigureAfter 未按预期工作

我有 3 个 spring-boot-starter 项目

其中一个自动配置类具有以下代码:

@Configuration
@ConditionalOnClass(value = Config.class)
@AutoConfigureAfter(value = {FileGeneratorConfig.class, FileUploaderConfig.class})
public class JobConfig 
Run Code Online (Sandbox Code Playgroud)

FileGeneratorConfig 和 FileUploaderConfig 也是自动配置类。

我期望首先创建在 FileUploaderConfig 中创建的 bean。因此,对此进行测试,我在 JobConfig 和 FileUploaderConfig 中创建 bean 的方法中放置了一个断点。但断点首先击中 JobConfig,这让我相信我的 @AutoConfigureAfter 不起作用。这是正确的假设吗?

另外在 FileUploaderConfig 我有这个:

@Bean
    FileUtilContainer fileUtilContainer(FileUtilContainerProperties fileUtilContainerProperties){
        return new FileUtilContainer(FileUtil.createDirectory(fileUtilContainerProperties.getArchive()),
                                     FileUtil.createDirectory(fileUtilContainerProperties.getWorking()),
                                     FileUtil.createDirectory(fileUtilContainerProperties.getConfirmation()), 
                                     FileUtil.createDirectory(fileUtilContainerProperties.getConfirmationProcessed()),
                                     FileUtil.createDirectory(fileUtilContainerProperties.getError()), 
                                     FileUtil.createDirectory(fileUtilContainerProperties.getErrorProcessed()));
    }
Run Code Online (Sandbox Code Playgroud)

和 FileUtilContainerProperties:

@Component
@ConfigurationProperties(prefix = "batch.letter.directory", ignoreUnknownFields = false)
public class FileUtilContainerProperties
Run Code Online (Sandbox Code Playgroud)

但它没有创建 FileUtilContainerProperties bean。我在这里错过了什么吗?

spring-annotations spring-boot

6
推荐指数
1
解决办法
9862
查看次数

使用 @Value Spring 注解从 .yaml 读取的属性映射的正确用法是什么

我通过以下方式从 Spring Boot 应用程序中的某些 .yaml 读取的地图中注入了属性:

@Value("#{${app.map}}")
private Map<String, String> indexesMap = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)

但两者都没有

app:
    map: {Countries: 'countries.xlsx', CurrencyRates: 'rates.xlsx'} 
    //note values in single quotes  

nor
app:
    map: {Countries: "countries.xlsx", CurrencyRates: "rates.xlsx"}
Run Code Online (Sandbox Code Playgroud)

(如https://www.baeldung.com/spring-value-annotation中所述)

也不

app:
    map:
      "[Countries]": countries.xslx
      "[CurrencyRates]": rates.xlsx
Run Code Online (Sandbox Code Playgroud)

(如/sf/answers/3622578641/所建议)

有效 - 我不断收到消息“自动装配依赖项注入失败;嵌套异常是 java.lang.IllegalArgumentException:无法解析占位符'

同时这也有效:

@Value("#{{Countries: 'countries.xlsx', CurrencyRates: 'rates.xlsx'}}")
private Map<String, String> indexesMap = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)

但我想将属性外部化

spring yaml dependency-injection spring-annotations spring-boot

6
推荐指数
1
解决办法
4697
查看次数

如何检测@Cacheable方法输出是否来自缓存?

有一个用@Cacheable注释的方法返回一个对象:

@Service
public class UserService {

  @Cacheable("userData")
  public UserData getUserData(String userName) {
    UserData userData = new UserData();
    userData.setGotFromCache(false);
    return userData;
  }

}
Run Code Online (Sandbox Code Playgroud)

和 UserData 对象:

@Getter
@Setter
public class UserData {
  private boolean gotFromCache;
}
Run Code Online (Sandbox Code Playgroud)

如何检测@Cacheable注解的方法是否被调用或者其输出是否来自缓存?

解决方法是注入 CacheManager 并手动检测它:

Cache cache = this.cacheManager.getCache("userData");
UserData userData = null;
String userName = "some user name";
if (cache != null) {
  Object key = SimpleKeyGenerator.generateKey(userName);
  userData = cache.get(key, UserData.class);
  if (userData != null) {
    userData.setGotFromCache(true);
  } else {
    userData = userService.getUserData(userName);
    cache.put(key, userData); …
Run Code Online (Sandbox Code Playgroud)

spring ehcache spring-annotations spring-cache

6
推荐指数
1
解决办法
2028
查看次数

在@Document indexName 中使用的 SpEL 与 spring 数据 elasticsearch 和 spring boot 没有被解析

寻找使用 SpEL 内部@Document注释的一些帮助,参考:

spring-data-elasticsearch:3.2.3.RELEASE 和弹簧靴 2.2.1 RELEASE

我在用谷歌搜索帮助解决这个问题时遇到了麻烦,因为关键字选择了不相关的问题(我已经看到了关于动态 indexName另一个(未回答的)问题)。

我想设置

@Document(indexName = "${es.index-name}", ...)

用my 中写入indexName的属性 ( es.index-name) 值派生的值application.properties

它改为使用文字字符串值"${es.index-name}"作为索引名称!

我也试过创建一个@ComponentEsConfig

带有indexName注释的字段@Value("${es.index-name}")

然后尝试使用 SpEL 访问此组件属性值:

@Document(indexName = "#{esConfig.indexName}", ...)

但这也不起作用(仍然解析为文字字符串并抱怨大写)。我已经通过调试器确认EsConfig组件正在正确解析 SpEL 并提供正确的值。但到达时失败@Document

以下是完整的代码片段:

利用@Document与规划环境地政司访问application.properties

import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Data
@Document(indexName = "${es.index-name}", type = "tests")
public class TestDocument { …
Run Code Online (Sandbox Code Playgroud)

spring-annotations spring-el spring-boot spring-data-elasticsearch

6
推荐指数
1
解决办法
1053
查看次数

将值从 Spring 元注释传递到另一个注释

我的用例:
我将@PreAuthorize在表单中有很多注释@PreAuthorize("hasAuthority('RESPECT_MY_AUTHORITY')")
我想创建一个元注释@HasAuthority,它将权限作为值并将其传递给@PreAuthorize("hasAuthority(<value>)").

感觉好像不可能了。我最接近我想要的是@AliasFor注释之类的东西。但问题是我无法为我将获得的价值添加任何东西@HasAuthority。所以我每次都必须重复 hasAuthority 部分。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasAuthority('RESPECT_MY_AUTHORITY')")
public @interface HasAuthority {

    @AliasFor(annotation = PreAuthorize.class, attribute = "value")
    String value();

}
Run Code Online (Sandbox Code Playgroud)

我想要类似的东西:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasAuthority(#value)")
public @interface HasAuthority {

    String value();

}
Run Code Online (Sandbox Code Playgroud)

知道我怎么能做到这一点,或者是否有可能?

spring-annotations

6
推荐指数
0
解决办法
141
查看次数