“Spring boot + mybatis”项目创建后“SpringApplication.run”可以启动,如果使用外部tomcat,注入(inject)dao报错
App
@Configuration
@ComponentScan(basePackages = "com.grass.module", excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class})})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig {
@Bean
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}
}
Application.java
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
DataSourceConfig.java
@Configuration
@EnableTransactionManagement
@MapperScan("com.grass.module")
public class DataSourceConfig implements EnvironmentAware {
private RelaxedPropertyResolver propertyResolver;
private static Logger logger = LoggerFactory.getLogger(DataSourceConfig.class);
@Override
public void setEnvironment(Environment env) {
this.propertyResolver = new RelaxedPropertyResolver(env, "db.");
}
@Bean
public DataSource dataSource() {
logger.info("================================start init datasource =======================");
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(propertyResolver.getProperty("jdbc.url"));
dataSource.setDriverClassName(propertyResolver.getProperty("jdbc.driverClass"));
dataSource.setUsername(propertyResolver.getProperty("jdbc.username"));
dataSource.setPassword(propertyResolver.getProperty("jdbc.password"));
logger.info("================================end init datasource=======================");
return dataSource;
}
@Bean(name = "transactionManager")
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
return dataSourceTransactionManager;
}
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
logger.info("================================start init sqlSessionFactory =======================");
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
Interceptor[] interceptors = new Interceptor[1];
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
// <!-- 4.0.0以后版本可以不设置该参数 -->
// <property name="dialect" value="mysql"/>
// <!-- 该参数默认为false -->
// <!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
// <!-- 和startPage中的pageNum效果一样-->
// <property name="offsetAsPageNum" value="true"/>
// <!-- 该参数默认为false -->
// <!-- 设置为true时,使用RowBounds分页会进行count查询 -->
// <property name="rowBoundsWithCount" value="true"/>
// <!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
// <!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型)-->
// <property name="pageSizeZero" value="true"/>
// <!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
// <!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
// <!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
// <property name="reasonable" value="false"/>
// <!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
// <!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
// <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值 -->
// <!-- 不理解该含义的前提下,不要随便复制该配置 -->
// <property name="params" value="pageNum=start;pageSize=limit;"/>
// <!-- 支持通过Mapper接口参数来传递分页参数 -->
// <property name="supportMethodsArguments" value="true"/>
// <!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
// <property name="returnPageInfo" value="check"/>
properties.put("dialect", "mysql");
properties.put("rowBoundsWithCount", true);
properties.put("pageSizeZero", false);
properties.put("reasonable", true);
properties.put("supportMethodsArguments", true);
properties.put("returnPageInfo", "check");
pageHelper.setProperties(properties);
interceptors[0] = pageHelper;
sessionFactory.setPlugins(interceptors);
sessionFactory.setTypeAliasesPackage(propertyResolver.getProperty("mybatis.typeAliasesPackage"));
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(propertyResolver.getProperty("mybatis.mapperLocations")));
logger.info("================================end init sqlSessionFactory =======================");
return sessionFactory.getObject();
}
}
MvcConfig.java
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.grass.module"}, includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class})
})
@ConfigurationProperties(prefix = "spring.mvc.")
public class MvcConfig extends WebMvcConfigurerAdapter {
@Value("prefix")
private String prefix;
@Value("suffix")
private String suffix;
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(prefix);
resolver.setSuffix(suffix);
return resolver;
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
super.addViewControllers(registry);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}
}
WebInitializer.java
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
/*
* DispatcherServlet的映射路径
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
/*
* 应用上下文,除web部分
*/
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
protected Class[] getRootConfigClasses() {
return new Class[]{AppConfig.class};
}
/*
* web上下文
*/
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
protected Class[] getServletConfigClasses() {
return new Class[]{MvcConfig.class};
}
/*
* 注册过滤器,映射路径与DispatcherServlet一致,路径不一致的过滤器需要注册到另外的WebApplicationInitializer中
*/
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
return new Filter[]{characterEncodingFilter};
}
}
UserController.java
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/findAll")
@ResponseBody
public List<UserEntity> findAll() {
return userService.findAll();
}
}
UserService.java
@Service
public class UserService {
@Autowired
private UserDao userDao;
public List<UserEntity> findAll() {
// return null;
return userDao.findAll();
}
}
UserDao.java
@Repository
public interface UserDao {
@Select("select name,age from sys_user")
List<UserEntity> findAll();
}
tomcat运行
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry 221 getSingleton - Creating shared instance of singleton bean 'userService'
16:26:37.201 DEBUG org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory 448 createBean - Creating instance of bean 'userService'
16:26:37.206 DEBUG org.springframework.beans.factory.annotation.InjectionMetadata 72 checkConfigMembers - Registered injected element on class [com.grass.module.sys.service.UserService]: AutowiredFieldElement for private com.grass.module.sys.dao.UserDao com.grass.module.sys.service.UserService.userDao
16:26:37.206 DEBUG org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory 529 doCreateBean - Eagerly caching bean 'userService' to allow for resolving potential circular references
16:26:37.210 DEBUG org.springframework.beans.factory.annotation.InjectionMetadata 86 inject - Processing injected element of bean 'userService': AutowiredFieldElement for private com.grass.module.sys.dao.UserDao com.grass.module.sys.service.UserService.userDao
16:26:37.215 WARN org.springframework.context.support.AbstractApplicationContext 546 refresh - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.grass.module.sys.dao.UserDao com.grass.module.sys.service.UserService.userDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.grass.module.sys.dao.UserDao] 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)}
16:26:37.215 DEBUG org.springframework.beans.factory.support.DefaultSingletonBeanRegistry 512 destroySingletons - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6ba90c6e: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,appConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor,userService,validator,org.springframework.aop.config.internalAutoProxyCreator]; root of factory hierarchy
16:26:37.218 ERROR org.springframework.web.context.ContextLoader 351 initWebApplicationContext - Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.grass.module.sys.dao.UserDao com.grass.module.sys.service.UserService.userDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.grass.module.sys.dao.UserDao] 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) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4810) ~[catalina.jar:8.0.32]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5255) ~[catalina.jar:8.0.32]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147) ~[catalina.jar:8.0.32]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725) ~[catalina.jar:8.0.32]
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701) ~[catalina.jar:8.0.32]
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717) ~[catalina.jar:8.0.32]
at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1692) ~[catalina.jar:8.0.32]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_73]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_73]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_73]
at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_73]
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300) ~[tomcat-coyote.jar:8.0.32]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) ~[?:1.8.0_73]
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) ~[?:1.8.0_73]
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:465) ~[catalina.jar:8.0.32]
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:415) ~[catalina.jar:8.0.32]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_73]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_73]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_73]
at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_73]
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300) ~[tomcat-coyote.jar:8.0.32]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) ~[?:1.8.0_73]
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) ~[?:1.8.0_73]
at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468) ~[?:1.8.0_73]
at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76) ~[?:1.8.0_73]
at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309) ~[?:1.8.0_73]
at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401) ~[?:1.8.0_73]
at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829) ~[?:1.8.0_73]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_73]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_73]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_73]
at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_73]
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323) ~[?:1.8.0_73]
at sun.rmi.transport.Transport$1.run(Transport.java:200) ~[?:1.8.0_73]
at sun.rmi.transport.Transport$1.run(Transport.java:197) ~[?:1.8.0_73]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_73]
at sun.rmi.transport.Transport.serviceCall(Transport.java:196) ~[?:1.8.0_73]
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) ~[?:1.8.0_73]
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) ~[?:1.8.0_73]
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$256(TCPTransport.java:683) ~[?:1.8.0_73]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_73]
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) [?:1.8.0_73]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_73]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_73]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_73]
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.grass.module.sys.dao.UserDao com.grass.module.sys.service.UserService.userDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.grass.module.sys.dao.UserDao] 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$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
... 58 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.grass.module.sys.dao.UserDao] 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.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:545) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
... 58 more
19-Apr-2016 16:26:37.231 SEVERE [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file
19-Apr-2016 16:26:37.232 SEVERE [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal Context [] startup failed due to previous errors
[2016-04-19 04:26:37,286] Artifact Gradle : com.grass:grass-web : grass-web-1.0-SNAPSHOT.war (exploded): Error during artifact deployment. See server log for details.
but use SpringApplication.run(Application.class, args) is ok
最佳答案
Spring Data can create implementations for you of @Repository interfaces of various flavors. Spring Boot will handle all of that for you as long as those @Repositories are included in the same package (or a sub-package) of your @EnableAutoConfiguration class.
Spring Boot tries to guess the location of your @Repository definitions, based on the @EnableAutoConfiguration it finds. To get more control, use the @EnableJpaRepositories annotation (from Spring Data JPA).
由于您的 WebInitializer
类不提供使用 @EnableAutoConfiguration
注释的配置类,您需要向某些配置类添加 @EnableJpaRepositories
注释,例如将其添加到 DataSourceConfig
。
关于java - 使用 'spring boot + mybatis'创建的项目使用 'spring Application'可以启动,如果使用外部tomcat,注入(inject)dao报错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36713775/