内容简介:根据异常信息,猜测是注入根据异常信息可知,Spring的IoC容器中并没有在
开发环境
JDK 1.8 Springboot 2.1.1.RELEASE
pom配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
关键代码
实体类
@Entity
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Repository
public interface UserRepository extends JpaRepository<User,Integer> {
}
自定义服务
@Service
public class MyService {
public void print(){
System.out.println(this.getClass().getSimpleName()+" call");
}
}
拦截器
public class SimpleInterceptor extends EmptyInterceptor {
@Resource
private MyService myService;
@Override
public String onPrepareStatement(String sql) {
myService.print();
System.out.println("sql:"+sql);
return super.onPrepareStatement(sql);
}
}
启动类
@SpringBootApplication
public class BootHibernateInterceptorProblemApplication {
public static void main(String[] args) {
SpringApplication.run(BootHibernateInterceptorProblemApplication.class, args);
}
}
配置
## DataSource spring.datasource.url=jdbc:mysql://localhost:3306/demo?characterEncoding=utf8&useSSL=true spring.datasource.username=root spring.datasource.password=123456789 ## hibernate spring.jpa.hibernate.ddl-auto=update ## add interceptor spring.jpa.properties.hibernate.ejb.interceptor=com.rjh.interceptor.SimpleInterceptor
单元测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class BootHibernateInterceptorProblemApplicationTests {
@Resource
private UserRepository userRepository;
@Test
public void contextLoads() {
System.out.println(userRepository.findAll());
}
}
运行结果
java.lang.NullPointerException
at com.rjh.interceptor.SimpleInterceptor.onPrepareStatement(SimpleInterceptor.java:20)
...
...
...
分析
根据异常信息,猜测是注入 MyService
失败
修改单元测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class BootHibernateInterceptorProblemApplicationTests {
@Resource
private UserRepository userRepository;
@Resource
private MyService myService;
@Resource
private SimpleInterceptor simpleInterceptor;
@Test
public void contextLoads() {
Assert.assertNotNull(myService);
Assert.assertNotNull(simpleInterceptor);
System.out.println(userRepository.findAll());
}
}
运行结果
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.rjh.interceptor.SimpleInterceptor' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)}
...
分析
根据异常信息可知,Spring的IoC容器中并没有 SimpleInterceptor
这个 Bean
,从此处可知 spring.jpa.properties.hibernate.ejb.interceptor=com.rjh.interceptor.SimpleInterceptor
并没有把这个拦截器注册到Spring容器中
失败方案
在 SimpleInterceptor
上添加 @Component
注解,将 SimpleInterceptor
注册到Spring容器中。同时注释 spring.jpa.properties.hibernate.ejb.interceptor
配置
失败: SimpleInterceptor
的构造方法触发了两次,添加到 Hibernate
中的 SimpleInterceptor
实例和注册到Spring容器中的 SimpleInterceptor
实例并不是同一个实例
解决方法
增加一个获取Spring的 ApplicationContext
实例的 工具 类,通过这个工具类调用需要注入的服务的方法
工具类
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext=applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
修改拦截器
public class SimpleInterceptor extends EmptyInterceptor {
@Override
public String onPrepareStatement(String sql) {
MyService myService= SpringContextUtil.getApplicationContext().getBean(MyService.class);
myService.print();
System.out.println("sql:"+sql);
return super.onPrepareStatement(sql);
}
}
执行结果
MyService call sql:select user0_.id as id1_0_, user0_.name as name2_0_ from user user0_ []
以上所述就是小编给大家介绍的《Springboot整合Hibernate拦截器时无法向拦截器注入Bean》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 为什么你写的拦截器中不能注入 Java bean?
- 前端架构之vue+axios 前端实现登录拦截(路由拦截、http拦截)
- react离开页面,自定义弹框拦截,路由拦截
- 基于原生fetch封装一个带有拦截器功能的fetch,类似axios的拦截器
- SpringMVC拦截器
- IOS 拦截器
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
About Face 3
Alan Cooper、Robert Reimann、David Cronin / John Wiley & Sons / 2007-5-15 / GBP 28.99
* The return of the authoritative bestseller includes all new content relevant to the popularization of how About Face maintains its relevance to new Web technologies such as AJAX and mobile platforms......一起来看看 《About Face 3》 这本书的介绍吧!