概述
一、Spring Bean定义常见错误
一.隐式扫描不到 Bean :@ComponentScan默认扫描范围
从启动类所在包开始,扫描当前包及其子级包下的所有文件。
@ComponentScan的使用位置为SpringBoot的启动类上,可以不加,不加的默认位置就是扫描当前包及其子级包下的所有文件。
如果需要扫描其他位置的,需要手动去指定,手动指定后,默认的范围就失效了。
@ComponentScan("com.testing")
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder().sources(Application.class).web(WebApplicationType.NONE).run(args);
}
}
二.定义的 Bean 缺少隐式依赖:无法将带参构造器加入容器
我们把一个类定义成 Bean,同时又觉得这个 Bean 的定义除了加了一些 Spring 注解外,并没有什么不同。所以在后续使用时,有时候我们会不假思索地去随意定义它,例如我们会写出下面这样的代码:
@Service
public class ServiceImpl {
private String serviceName;
public ServiceImpl(String serviceName){
this.serviceName = serviceName;
}
}
报这个错误:
Parameter 0 of constructor in com.spring.puzzle.class1.example2.ServiceImpl required a bean of type 'java.lang.String' that could not be found.
1、问题原因
定义一个类为 Bean,如果再显式定义了构造器,那么这个 Bean 在构建时,会自动根据构造器参数定义寻找对应的 Bean,然后反射创建出这个 Bean。
作为BEAN对象,需要创建实例,在创建实例的时候,会调用构造器,这里的构造器只有一个带参构造器,但是这个参数谁也不知道。
2、处理方法
是因为无法找到这个入参,所以才会报错,那么我们把这个入参作为一个BEAN对象交给容器就可以了。
声明一个CONFIG类,将该对象交给BEAN容器
@Configuration
public class configdemo {
@Bean
public String servicename() {
return "test";
}
}
三.原型 Bean 被固定:设置为多例,但是访问仍然是单例
即使将ServiceImpl 设置为多例,但是无论怎么访问依然是单例。
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ServiceImpl {
}
@RestController
public class controllerdemo {
@Autowired
private serviceimpldemo serviceImpl;
@GetMapping("/hi}")
@ResponseBody
public String hi() {
return "helloworld, service is : " + serviceImpl;
}
}
1、问题原因
当一个单例的 Bean,使用 autowired 注解标记其属性时,这个属性值会被固定下来。
2、处理方法(注:原service依然要设置为多例模式)
修正这个问题,肯定是不能将 ServiceImpl 的 Bean 固定到属性上的,而应该是每次使用时都会重新获取一次。所以这里提供了3种修正方式:
1.@Lookup
@Controller
public class controllerdemo {
// @Autowired
// private serviceimpldemo serviceImpl;
@GetMapping("/hi")
@ResponseBody
public String hi() {
return "helloworld, service is : " + getServiceImpl();
}
@Lookup
public serviceimpldemo getServiceImpl() {
return null;
}
}
2.自动注入 ApplicationContext
@Controller
public class controllerdemo {
@Autowired
private ApplicationContext applicationContext;
@GetMapping("/hi")
@ResponseBody
public String hi() {
return "helloworld, service is : " + getServiceImpl();
}
@Lookup
public serviceimpldemo getServiceImpl() {
return applicationContext.getBean(serviceimpldemo.class);
}
}
3.将service设置为从代理对象中获取
@Service
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class serviceimpldemo {
}
@Controller
public class controllerdemo {
@Autowired
private serviceimpldemo serviceImpl;
@GetMapping("/hi")
@ResponseBody
public String hi() {
return "helloworld, service is : " + serviceImpl;
}
}
最后
以上就是积极电灯胆为你收集整理的Spring编程常见错误--Spring Core篇-01 |Spring Bean 定义常见错误一、Spring Bean定义常见错误的全部内容,希望文章能够帮你解决Spring编程常见错误--Spring Core篇-01 |Spring Bean 定义常见错误一、Spring Bean定义常见错误所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复