英文:
Can't achieve dependency injection oustide a controller in Spring Booot
问题
我是Spring MVC框架的新手,目前正在开发一个使用会话范围Bean控制某些数据流的Web应用程序。我可以在控制器中使用*@Autowired注解访问应用程序上下文中的这些Bean,没有任何问题。但是,当我在服务层中使用一个没有任何请求映射(@RequestMapping*、@GetMapping或*@PostMapping*)注解的类时,问题就出现了。当我尝试直接访问应用程序上下文,或者使用*@Autowired或@Resource注解时,该Bean的值为null*。
我有一个如下所示的配置类:
@Configuration
@EnableAspectJAutoProxy
@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class, basePackages = "com.quantumx.nitididea.NITIDideaweb.repository")
public class AppConfig implements WebMvcConfigurer {
@Bean (name = "lastTemplate")
@SessionScope
public LastTemplate getlastTemplate() {
return new LastTemplate();
}
//一些额外的代码
}
POJO类定义如下:
public class LastTemplate {
private Integer lastId;
public LastTemplate(){
}
public Integer getLastId() {
return lastId;
}
public void setLastId(Integer lastId) {
this.lastId = lastId;
}
}
然后我有一个被注解为服务的测试类,没有任何请求映射的注解方法:
//@Controller
@Service
public class Test {
// @Autowired
// private ApplicationContext context;
// @Autowired
@Resource(name = "lastTemplate")
public LastTemplate lastTemplate;
// @Autowired
// public void setLastTemplate(LastTemplate lastTemplate) {
// this.lastTemplate = lastTemplate;
// }
public Test() {
}
// @RequestMapping("/test")
public String testing() {
// TemplateForma last = (TemplateForma) context.getBean("lastInsertedTemplate");
// System.out.println(last);
System.out.println(lastTemplate);
// System.out.println(context.containsBean("lastTemplate"));
// System.out.println(context.getBean("lastTemplate"));
System.out.println("Testing complete");
return "Exit from testing method";
// return "/Messages/Success";
}
}
正如您所见,有很多被注释掉的代码,展示了我尝试访问应用程序上下文的所有方式,包括使用应用程序上下文依赖项、自动装配、声明资源以及尝试使用请求映射。如果不使用控制器注解和请求映射方法,则Bean为空,并且在使用上下文的getBean()方法时会抛出Java空指针异常。
最后,我只是在我的应用程序中的一个控制器中测试了一下我的类:
@RequestMapping("/all")
public String showAll(Model model) {
Test test = new Test();
test.testing();
return "/Administrator/test";
}
值得一提的是,我还尝试将Bean的范围更改为应用程序范围和单例,但没有成功。如何在没有通过控制器映射请求的情况下,在服务类中访问我的应用程序上下文呢?
英文:
I am new at spring MVC framework and i am currently working in a web application that uses a session scoped bean to control some data flow.
I can access these beans in my application context using @Autowired annotation without any problem in the controllers. The problem comes when I use a class in service layer that does not have any request mapping (@RequestMapping, @GetMapping nor @PostMapping) annotation.
When I try to access the application context directly or using @Autowired or even the @Resource annotation the bean has a null value.
I have a configuration class as follow:
@Configuration
@EnableAspectJAutoProxy
@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class, basePackages = "com.quantumx.nitididea.NITIDideaweb.repository")
public class AppConfig implements WebMvcConfigurer {
@Bean (name = "lastTemplate")
@SessionScope
public LastTemplate getlastTemplate() {
return new LastTemplate();
}
//Some extra code
}
The POJO class is defined as :
public class LastTemplate {
private Integer lastId;
public LastTemplate(){
}
public Integer getLastId() {
return lastId;
}
public void setLastId(Integer lastId) {
this.lastId = lastId;
}
}
The I have a Test class that is annotated as service and does not have any request mapping annotated method:
//@Controller
@Service
public class Test {
// @Autowired
// private ApplicationContext context;
// @Autowired
@Resource(name = "lastTemplate")
public LastTemplate lastTemplate;
// @Autowired
// public void setLastTemplate(LastTemplate lastTemplate) {
// this.lastTemplate = lastTemplate;
// }
public Test() {
}
// @RequestMapping("/test")
public String testing() {
// TemplateForma last = (TemplateForma) context.getBean("lastInsertedTemplate");
// System.out.println(last);
System.out.println(lastTemplate);
// System.out.println(context.containsBean("lastTemplate"));
// System.out.println(context.getBean("lastTemplate"));
System.out.println("Testing complete");
return "Exit from testing method";
// return "/Messages/Success";
}
}
As you can see, there is a lot of commented code to show all the ways i have been trying to access my application context, using an Application context dependency, autowiring, declaring a resource and trying with a request mapping. The bean is null if no controller annotation and request mapping method is used and throws a java null pointer exception when I use the context getBean() methods.
Finally I just test my class in a controller that i have in my app:
@RequestMapping("/all")
public String showAll(Model model) {
Test test = new Test();
test.testing();
return "/Administrator/test";
}
Worth to mention that I also tried to change the scope of the bean to a Application scope and singleton, but it not worked. How can access my application context in a service class without mapping a request via controller?
答案1
得分: 0
> 值得提到的是,我还尝试将Bean的范围更改为应用程序范围(Application scope)和单例(singleton),但这并没有起作用。
在这种情况下,它应该是可以工作的。
> 在不通过控制器映射请求的情况下,如何在服务类中访问我的应用程序上下文?
尝试以下之一:
@Autowired private ApplicationContext appContext;
或者
在你想要访问它的类中实现 ApplicationContextAware
接口。
编辑:
如果你仍然想从非 Spring 管理的类中访问 ApplicationContext
。这是一篇教程,展示了如何实现这一目标。
这个页面提供了一个示例,展示了如何在非 Spring 管理的类中获取 Spring 应用程序上下文对象。
英文:
> Worth to mention that I also tried to change the scope of the bean to a Application scope and singleton, but it not worked
It should have worked in this case.
> How can access my application context in a service class without mapping a request via controller?
Try one of these :-
@Autowired
private ApplicationContext appContext;
OR
Implement ApplicationContextAware
interface in the class where you want to access it.
Edit:
If you still want to access ApplicationContext
from non spring managed class. Here is the link to article which shows how it can be achieved.
答案2
得分: 0
以下是翻译好的部分:
我成功的做法是将会话范围的 Bean 从应用程序配置声明中移除,并移到 POJO 定义中,如下所示:
@Component
@SessionScope
public class LastTemplate {
private Integer lastId;
public LastTemplate(){
}
public Integer getLastId() {
return lastId;
}
public void setLastId(Integer lastId) {
this.lastId = lastId;
}
}
然后我使用 *@Autowired* 注解来调用这个 Bean。
英文:
What worked for me is that session scoped bean had to be removed in the application configuration declaration and moved to the POJO definition as follows:
@Component
@SessionScope
public class LastTemplate {
private Integer lastId;
public LastTemplate(){
}
public Integer getLastId() {
return lastId;
}
public void setLastId(Integer lastId) {
this.lastId = lastId;
}
}
The I just call the bean using @Autowired annotation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论