在Spring中是否有一种方法可以使用类型及其任何子类型的所有bean自动填充列表?我有一个setter方法,看起来像:
setMyProp(List<MyType> list)
Run Code Online (Sandbox Code Playgroud)
我想在MyType的任何bean和MyType的所有子类中自动装配.
谢谢,杰夫
在带有注释的Spring MVC中,我们使用@Controller标记任何POJO.在这个控制器中,我们可以使用autowired属性获取WebApplicationContext.
@Controller
public class HomePageController {
@Autowired
ApplicationContext act;
@RequestMapping("/*.html")
public String handleBasic(){
SimpleDomain sd = (SimpleDomain)act.getBean("sd1");
System.out.println(sd.getFirstProp());
return "hello";
}
Run Code Online (Sandbox Code Playgroud)
但是在这种方法中,我们没有方便的servletContext.那么我们仍然可以使用较旧的方式获取WebApplicationContext吗?即
WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)
Run Code Online (Sandbox Code Playgroud)
我们如何在这里获得servletContext?
我没有任何强迫使用旧方式; 所以这个问题只是出于好奇心来检查弹簧的灵活性.它也可以是一个面试问题.
我想实现方法安全性.
我遇到了@Secured和@PreAuth注释的问题.每当我将任何这些添加到我的服务接口时,我都会收到如下例外情况.没有它们,我的应用运行得很好.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'methodSecurityInterceptor' defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.aopalliance.intercept.MethodInterceptor org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.methodSecurityInterceptor() throws java.lang.Exception] threw exception; nested exception is org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
Run Code Online (Sandbox Code Playgroud)
它是一个REST服务应用程序.
以下是我的配置的一些相关部分.如果我还要添加其他内容,请告诉我.
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig {
...
@Autowired
private DatabaseAuthenticationProvider databaseAuthenticationProvider;
...
@Configuration
@Order(1)
public static class RestWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
...
@Override
protected void configure(HttpSecurity http) throws Exception {
...
http …Run Code Online (Sandbox Code Playgroud) 这真的很奇怪.我开始将Spring Boot项目作为一个单独的maven项目开始,并且完美无缺.基本上它是一个带有安全性和邮件的Spring MVC应用程序.
然后,当我看到一些组件(如服务,存储库,模型)将被独立应用程序重用时,我决定将maven项目拆分为子模块.
突然没有自动装配开始工作.经过一番调查后,我发现我需要将这些软件包明确地放在我的独立应用程序的应用程序中:
@ComponentScan (basePackages={"service"})
@EnableJpaRepositories(basePackages={"repository"})
@EnableAutoConfiguration
@EntityScan(basePackages={"model"})
Run Code Online (Sandbox Code Playgroud)
好的,之后我的自定义类开始自动装配.但是出现了另一个问题
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.mail.javamail.JavaMailSender service.impl.UserServiceImpl.mailSender; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSender] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at …Run Code Online (Sandbox Code Playgroud) 我想创建一个在请求生命周期中唯一的UUID.为此,我使用@Scope("request")注释创建一个UUID bean.
@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST)
public UUID requestUUID() {
return UUID.randomUUID();
}
Run Code Online (Sandbox Code Playgroud)
我想在我的控制器中访问这个bean.所以我用@Autowired注入它.这很好用.
@Controller
public class DashboardController {
@Autowired
UUID uuid;
@Autowired
WelcomeMessageService welcomeMessageService;
@Autowired
IssueNotificationService issueNotificationService;
@RequestMapping("/")
public String index(Model model) throws InterruptedException, ExecutionException {
System.out.println(uuid);
PortalUserDetails userLog = getPortalUserDetails();
BusinessObjectCollection<WelcomeMessage> welcomeMessages = welcomeMessageService.findWelcomeMessages(
20,
0,
userLog.getZenithUser(),
userLog.getConnectionGroup().getConnectionGroupCode(),
"FR");
if(welcomeMessages!=null) {
model.addAttribute("welcomeMessages", welcomeMessages.getItems());
}
BusinessObjectCollection<IssueNotification> issueNotifications =
issueNotificationService.findIssueNotifications(userLog.getZenithUser());
if(welcomeMessages!=null) {
model.addAttribute("welcomeMessages", welcomeMessages.getItems());
}
model.addAttribute("issueNotifications", issueNotifications);
return "index";
}
}
Run Code Online (Sandbox Code Playgroud)
控制器调用多个服务.每个服务都使用RestTemplate bean.在这个RestTemplate bean中,我想得到UUID.
@Component
public class ZenithRestTemplate extends RestTemplate …Run Code Online (Sandbox Code Playgroud) 假设我的接口扩展CrudRepository如下
@Repository
public interface EmployeeRepository extends CrudRepository<Employee, Integer>
{
}
Run Code Online (Sandbox Code Playgroud)
我在Service类中使用EmployeeRepository接口,如下所示
@Service
public class EmployeeService
{
@Autowired
EmployeeRepository employeeRepository;
public List<Employee> getAllEmployee()
{
List<Employee> listEmp=new ArrayList<Employee>();
employeeRepository.findAll().forEach(listEmp::add);
return listEmp;
}
}
Run Code Online (Sandbox Code Playgroud)
和控制器如下
@RestController
public class WelcomeController
{
@Autowired
EmployeeService empservice;
@RequestMapping("/employees")
public List<Employee> getEmployees()
{
return empservice.getAllEmployee();
}
}
Run Code Online (Sandbox Code Playgroud)
它给出了以下例外
org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为'welcomeController'的bean时出错:通过字段'empservice'表示的不满意的依赖关系:创建名为'employeeService'的bean时出错:通过字段'employeeRepository'表示的不满意的依赖关系
错误很明显,因为任何类都没有实现接口EmployeeRepository
@Autowired
EmployeeRepository employeeRepository;
Run Code Online (Sandbox Code Playgroud)
自动装配将失败,因为没有类正在实施employeeRepository.
尽管如此,我对它如何工作感到困惑,因为我在GitHub和教程上看到的每个代码都运行得很好.
我在哪里出错了@Autowired如何处理扩展CrudRepository的接口,即使没有类正在实现它; 这是自动装配的基本规则?也就是说,如果您要自动连接任何接口,那么至少有一个类必须实现该接口,然后自动装配将成功.
我有弹簧应用程序(球衣2.6类和servlet).
我需要从泽西/非弹簧环境中获取Spring bean(s),
类似的问题建议在上下文的静态包装中获取上下文
public static ApplicationContext getContext() {
return context;
}
Run Code Online (Sandbox Code Playgroud)
如何确定上下文已加载或不为null?
如果我不能,我应该等待/检查,直到它加载弹簧上下文?
在从泽西上下文调用或从简单的HttpServlet代码调用bean的情况下
编辑
Jersey使用jersey-spring3依赖jar 工作正常,所以我的问题只是关于Servlets的Spring控件
编辑2
该应用程序正在加载不同于@entpnerd建议文章的弹簧
它注册了一个实现的Servlet WebApplicationInitializer
public class MyWebAppInitializer implements WebApplicationInitializer {
Run Code Online (Sandbox Code Playgroud)
但是也在DispatcherServletweb.xml中配置了
如何才能DispatcherServlet在Spring加载后加载?
因为我们在其init方法上添加了自动装配功能:
WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext())
.getAutowireCapableBeanFactory().autowireBean(this);
Run Code Online (Sandbox Code Playgroud)
在提供请求之前添加超时是最喜欢的解决方案还是在类加载中有一个可以处理它的调整?
编辑3
在普通的Spring中,当我们想自动连接一个接口时,我们在Spring上下文文件中定义它的实现。那Spring Boot呢?我们怎样才能做到这一点?目前,我们仅自动装配不是接口的类。这个问题的另一部分是关于在Spring启动项目中的Junit类中使用类。例如,如果我们要使用CalendarUtil,则如果我们自动连接CalendarUtil,它将抛出空指针异常。在这种情况下我们该怎么办?我现在刚刚使用“新”进行了初始化...
我创建了一个调度程序类
public class TestSchedulderNew {
@Scheduled(fixedDelay = 3000)
public void fixedRateJob1() {
System.out.println("Job 1 running");
}
@Scheduled(fixedDelay = 3000)
public void fixedRateJob2() {
System.out.println("Job 2 running");
}
}
Run Code Online (Sandbox Code Playgroud)
在配置中,我放置了 @ConditionalOnProperty 注释以在有条件的情况下启用此功能。
@Bean
@ConditionalOnProperty(value = "jobs.enabled")
public TestSchedulderNew testSchedulderNew() {
return new TestSchedulderNew();
}
Run Code Online (Sandbox Code Playgroud)
现在在控制器中,我创建了“stopScheduler”方法来停止那些调度程序,在这个控制器中我有自动装配的 TestSchedulderNew 类
@RestController
@RequestMapping("/api")
public class TestCont {
private static final String SCHEDULED_TASKS = "testSchedulderNew";
@Autowired
private ScheduledAnnotationBeanPostProcessor postProcessor; /]
@Autowired
private TestSchedulderNew testSchedulderNew;
@GetMapping(value = "/stopScheduler")
public String stopSchedule(){
postProcessor.postProcessBeforeDestruction(testSchedulderNew,
SCHEDULED_TASKS);
return "OK";
}
} …Run Code Online (Sandbox Code Playgroud) @Mapper(componentModel = "spring")
public interface DemoConvert {
public static DemoConvert INSTANCE = mappers.getMapper(DemoConvert.class);
@AutoWired
private PersonInfoSearchService personInfoSearchService;
@Mapping(source = "name", target = "name")
@Mapping(source = "id", target = "gender", expression = "java(personInfoSearchService.searchGenderById(id))")
PersonDTO toPerson(TeacherDTO teacherDTO);
}
Run Code Online (Sandbox Code Playgroud)
如何一起使用mapstruct和springboot bean?@自动连线
autowired ×10
spring-boot ×7
java ×6
spring ×6
servlets ×2
spring-mvc ×2
classloader ×1
javabeans ×1
junit ×1
mapstruct ×1
maven ×1
spring-data ×1