我正在尝试将JPA用于我的spring应用程序。我已经集成了JPATransactionManager&将LocalEntityManagerFactoryBean转换为AppConfig类。现在,当我尝试调用DaoImpl中的方法之一时,AppConfig无法对类进行自动装配。这是我的代码
Test Class
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
BbDao personService = context.getBean(BbDao.class);
personService.getDealByDealId("0194541605021NJMAPFU");
context.close();
}
}
@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan(basePackages = "net.bb.spring")
public class AppConfig{
@Bean
public LocalEntityManagerFactoryBean getEntityManagerFactoryBean() {
LocalEntityManagerFactoryBean factoryBean = new LocalEntityManagerFactoryBean();
factoryBean.setPersistenceUnitName("MyPersistence");
return factoryBean;
}
@Bean
public JpaTransactionManager geJpaTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(getEntityManagerFactoryBean().getObject());
return transactionManager;
}
}
@RestController
public class ConfirmPurchaseController {
private Logger logger = Logger.getLogger(ConfirmPurchaseController.class);
@Autowired
private MyService myService;
@GetMapping("/purchase")
public ResultDto confirmpurchase(HttpServletResponse response) throws ClassNotFoundException, IOException {
// Business Logic
}
}
@Component
public interface MyService {
// Methods defined
}
@Service
public class MyServiceImpl implements MyService, ServletContextAware {
private ServletContext servletContext;
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
public ServletContext getServletContext() {
return servletContext;
}
// Added the implemented methods of the MyService Interface
}
它抛出的例外是
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myServiceImpl': Unsatisfied dependency expressed through field 'servletContext'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.servlet.ServletContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
,错误日志为
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'confirmPurchaseController': Unsatisfied dependency expressed through field 'myService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myServiceImpl': Unsatisfied dependency expressed through field 'servletContext'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.servlet.ServletContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
at net.bb.spring.controller.Test.main(Test.java:14)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myServiceImpl': Unsatisfied dependency expressed through field 'servletContext'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.servlet.ServletContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 14 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.servlet.ServletContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 27 more
任何想法对我都非常有用。
P.S:我使用配置作为注释,没有XML
答案 0 :(得分:0)
这不是答案,但我还不能添加评论。
您是否尝试通过setter方法自动装配ServletContext? - 从属性中删除@Autowired - 删除你的一个setter上下文(不必要的重复) - 将setter标记为@Autowired
此外,从MyService中删除@Component注释,如果在其实现中使用@Service注释,则没有必要。
答案 1 :(得分:0)
根据Apache Tomcat文档,ServletContext
定义servlet用于与其通信的一组方法 servlet容器。
每个Java虚拟机每个“Web应用程序”有一个上下文。 (“Web应用程序”是安装的servlet和内容的集合 在服务器的URL命名空间的特定子集下,例如/ catalog 并可能通过.war文件安装。)
这意味着ServletContext仅在像Apache Tomcat这样的Servlet容器中有效。但正如我所看到的,您正试图通过在main方法中创建bean来运行普通的Java应用程序,这会使ServletContext
的存在无效。
所以你需要做的是:
步骤1:构建AppConfig并覆盖所需的方法。
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"net.bb.spring"})
public class AppConfig extends WebMvcConfigurerAdapter {
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/");
}
//....
}
第2步:创建WebInitializer以初始化Dispatcher Servlet
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] {AppConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
步骤3:创建服务层以自动装配ServletContext
@Service
public class MyServiceImpl implements MyService {
private ServletContext servletContext;
@Autowire
public MyServiceImpl(ServletContext servletContext) {
this.servletContext = servletContext;
}
public ServletContext getServletContext() {
return servletContext;
}
//...
}
第4步:将应用程序构建到WAR文件
步骤5:将WAR文件部署到Tomcat的webapp文件夹(如果您使用的是Tomcat)
第6步:启动Tomcat
答案 2 :(得分:0)
这是您需要更改的内容:
1)您不需要使用@Component
注释接口,仅在实现类上需要注释
我的服务
public interface MyService {
// Methods defined
}
2)使用构造函数注入获得ServeletContext
的实例。
@Service
public class MyServiceImpl implements MyService, ServletContextAware {
private ServletContext servletContext;
@Autowire
public MyServiceImpl(ServletContext servletContext) {
this.servletContext = servletContext;
}
//TODO: other methods goes here...
}
请注意,ServletContext
不是Spring bean,因此除非实现ServletContextAware
,否则无法注入它。保持实现类implements
ServletContextAware