至少有两种方法可以将Spring bean放入上下文配置中:
- 在配置类中声明具有
@Bean
的方法。 - 在配置类上加上
@ComponentScan
。
我原本期望这两种方法在生成的Spring bean方面没有任何区别。
然而,我找到了一个示例来证明它们之间的差异:
// UserInfoService.java
public interface UserInfoService
{
@PreAuthorize("isAuthenticated()")
String getUserInfo ();
}
// UserInfoServiceTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextHierarchy({
@ContextConfiguration(classes = TestSecurityContext.class),
@ContextConfiguration(classes = UserInfoServiceTest.Config.class)
})
public class UserInfoServiceTest
{
@Configuration
public static class Config
{
@Bean
public UserInfoService userInfoService ()
{
return new UserInfoServiceImpl();
}
}
@Autowired
private UserInfoService userInfoService;
@Test
public void testGetUserInfoWithoutUser ()
{
assertThatThrownBy(() -> userInfoService.getUserInfo())
.isInstanceOf(AuthenticationCredentialsNotFoundException.class);
}
@Test
@WithMockUser
public void testGetUserInfoWithUser ()
{
String userInfo = userInfoService.getUserInfo();
assertThat(userInfo).isEqualTo("info about user");
}
上面的代码是用来测试服务中安全注解的,具体是在
UserInfoService
服务中。然而,它在testGetUserInfoWithoutUser()
上失败了。原因是userInfoService
这个bean没有被Spring Security代理。因此,调用userInfoService.getUserInfo()
没有被@PreAuthorize("isAuthenticated()")
注解所阻止。但是,如果我使用
@ComponentScan
替换@Bean
注解,一切都会开始工作。也就是说,userInfoService
这个bean将被代理,调用userInfoService.getUserInfo()
将被@PreAuthorize
注解所阻止。为什么
@Bean
和@ComponentScan
之间的方法不同?我漏掉了什么吗?注:完整示例在这里,上述修复方法在这里。
@Bean
,难道不应该在工厂方法上也注释@PreAuthorize
吗? - Marco Bolis