Spring Context init(java)
我是spring的初学者,我遇到了基本的上下文初始化问题,我找不到任何简单的教程。 所以我想做的是基本的dependency injection,我已经看到我只需要将类标记为@Componant或@Service,并使用@Autowired直接将它们注入目标fiels中。 为此,我需要正确设置我的spring上下文(我需要构建一个Web服务+使用JPA,所以我想构建一个webapp)
我正在使用JDK 1.8,maven 3.2.1
我想做一个基本的dependency injection。 =>我想在那里注入一个storeImpl实例,但这会导致空指针exception=>这项工作完全没有注入(私有商店storeImpl = new storeImpl();)
package com.mycompany.app.controller; @Controller public class Controller { @Autowired private Store storeImpl; public void use() { storeImpl.get(); } } package com.mycompany.app.store; public interface Store { boolean get(); } package com.mycompany.app.store; @Component public class StoreImpl implements Store { @Override public boolean get() { return true; } }
=>我的主要(我现在用这个测试我的应用程序):
public class App { public static void main(String[] args) { Controller controller = new Controller(); controller.use(); } }
=>我的pom.xml
4.0.0 com.mycompany.app my-app jar 1.0-SNAPSHOT my-app http://maven.apache.org 4.0.4.RELEASE junit junit 3.8.1 test org.jsoup jsoup 1.7.1 org.projectlombok lombok 1.12.6 provided org.springframework spring-core ${spring.version} org.springframework spring-context ${spring.version} org.springframework spring-context-support ${spring.version} org.springframework spring-web ${spring.version} org.springframework spring-webmvc ${spring.version} org.springframework spring-aop ${spring.version} org.springframework.data spring-data-jpa 1.5.2.RELEASE org.hibernate hibernate-core 4.3.5.Final javax.servlet javax.servlet-api 3.0.1 provided org.apache.maven.plugins maven-compiler-plugin 3.1 1.8 1.8
=>我的web.xml
Archetype Created Web Application dispatcher org.springframework.web.servlet.DispatcherServlet 1 dispatcher / contextConfigLocation /META-INF/spring-context.xml org.springframework.web.context.ContextLoaderListener
=>我的spring-context.xml
<!----> <!-- -->
=>我的项目架构
my-app src main java com.mycompagny.app controller Controller.java store Store.java StoreImpl.java app.java ressources META-INF spring-context.xml webapp WEB-INF web.xml test java pom.xml
=> main()的堆栈跟踪
Exception in thread "main" java.lang.NullPointerException at com.mycompany.app.controller.Controller.run(Controller.java:25) at com.mycompany.app.App.main(App.java:19) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
所以我的问题是我的注入字段(storeImpl)为null。 我想我错过了一些关于context init的东西? 再次感谢您的帮助和您的回答
您有几个问题(从您的post中可以看出以下内容)。
- 混合不同版本的Springjar子
- 注释的位置错误
- applicationcontext中的重复。
- 使用版本化的XSD文件。
- 在web.xml中发生冲突的版本控制
1.混合不同版本的Spring的jar子
org.springframework spring-core 4.0.3.RELEASE org.springframework spring-context 4.0.4.RELEASE org.springframework spring-context-support 4.0.3.RELEASE org.springframework spring-web 4.0.1.RELEASE org.springframework spring-webmvc 4.0.1.RELEASE javax.servlet servlet-api 2.5 org.springframework spring-aop 3.0.5.RELEASE
你的pom上堆满了不同弹簧版本的jar子(3.0.5,4.0.1,4.0.3和4.0.3)。 如果你想要麻烦,那么这就是你要走的路。 始终坚持单一版本的框架,不要混合来自不同版本的jar子。 这不仅适用于Spring,而是适用于每个(多jar)框架。
使用maven的强大function来帮助您,指定一个属性来保存您要使用的Spring版本并使用该属性。
4.0.4.RELEASE org.springframework spring-core ${spring.version} org.springframework spring-context ${spring.version} org.springframework spring-context-support ${spring.version} org.springframework spring-web ${spring.version} org.springframework spring-webmvc ${spring.version} org.springframework spring-aop ${spring.version}
您可能需要添加更多内容,具体取决于Spring Data JPA所引入的依赖项,如果它具有不同的版本。
2.注释的位置错误
@Service public interface Store { boolean get(); }
注释不是从接口inheritance的,因此将注释放在接口上几乎没用。 对于像@Transactional
这样的特定注释,Spring有一些hacks,但不适用于此。 将注释移动到具体实现,不要将其放在界面上。
@Service public class Controller { @Autowired private Store storeImpl; public void use() { storeImpl.get(); } }
我在这里看不到任何没有@Controller
或者什么也没有@RequestMapping
所以我不确定你认为Spring如何检测和处理这个类。
3.在applicationcontext中重复。
将其从您的上下文中删除,因为使用
已经暗示了这一点。
应仅在您的情况下由DispatcherServlet
加载的xml文件中(如果已发布实际代码)应该是dispatcher-servlet.xml
。
在两个xml文件中都有相同的
元素,这将导致bean复制。 ContextLoaderListener
加载的文件应加载@Controllers
任何文件,而DispatcherServlet
只应加载@Controllers
并忽略其他任何内容。 要在组件扫描时使用包含/排除filter。
将此用于ContextLoaderListener
。
将此用于DispatcherServlet
。
另外,不要将DispatcherServlet
的配置导入ContextLoaderListener
因为这将再次导致bean重复。
4.使用版本化的XSD文件。
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
您的架构位置使用版本化的XSD文件,建议使用无版本的xsd文件。 这将确保将加载属于当前spring版本的xsd版本。
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
5. web.xml中的版本冲突
你想要2.4版本的2.3是什么? 你在你的pom中包括servlet-api 2.5,我希望你想要3.0版本。 相应地更改标题(和maven依赖项)。
将web.xml
标头更改为以下内容。
更新您的pom.xml以包含servlet 3.0规范。
javax.servlet javax.servlet-api 3.0.1 provided
您必须在Spring xml中定义bean
因此,@ @Autowired
bean将由Spring框架注入