SpringBoot对不同Bean注解的区别和使⽤场景
⽂章⽬录
什么是Bean?
谈Bean的潜台词是在说Spring中的Bean,我们都知道Spring中的BeanFactory,⽽Bean这个概念也是由此⽽来。在Spring中,只要⼀个类能被实例化,并被Spring容器管理,这个类就称为⼀个Bean,或者SpringBean.
除此之外,我们还听到⼀些其他的词:
JavaBean、POJO、VO、DTO
这些叫法⼜是什么意思?使⽤的场景⼜是什么?
JavaBean
⼀个JavaBean是⼀个遵循Sun公司的类。JavaBean可以理解为java中可以复⽤的组件,它满⾜下⾯条件:
有⼀个公共的缺省构造⽅法
这个类的属性使⽤getter和setter来访问,并且命名遵从标准的规范
这个类可以序列化
POJO(Plain Ordinary Object )
POJO是⼀个历史遗留名称,为什么这样讲?因为POJO是⽤来指明该对象不同于Entity Beans
EntityBeans是EJB中的概念,⽽EJB在Spring出现后,就渐渐淡出了历史的舞台。所以,POJO在Martin Fowler提出时,就是指那些没有实现任何EJB接⼝的普通java类。⽽延⽤⾄今,严格讲,所有的java类,都是POJO,因为现在没有⼈在使⽤ejb这些⽼古董了。但是有时我们为了区分Spring Bean,可以将没有被Spring管理的类称为POJO。
VO (Value Object)
VO指⼀个对象例如 java.lang.Integer 它持有⼀些数据,或数据对象。这个概念是 Martin Fowler提出的概念。
DTO (Data Transfer Object)
DTO也是EJB种提出的⼀个概念,⽬的就是在数据传输时,通过直接传输对象,在⽹络中传输数据。
⼩结:
所以对我们⽽⾔,VO和DTO没有区别(但是Martin Fowler可能⽤它们表⽰了不同的细分概念),⽽⼤多数时候,它们遵循JavaBean规范,所以它们也都是JavaBean。当然,它们都是POJO。
可以看出,它们本质上都是在指⼀个java对象,为了区分场景和功能,有了不同的叫法。开发中有时还会出现,Entity, Domain等。⽤来表⽰对实体的映射,或表的映射。⼀般可以这样做来规范开发:
对于Spring管理的对象,称为Bean
映射到数据表的对象实体类,称为entity,放在entity⽬录
对于接⼝⽤于封装数据,⽐如接受⼀个json⼊参,为了⽅便,定义⼀个对象封装参数,可以叫dto (或pojo) 放在pojo包,以表明它不是某个表的映射类。
注解@Bean @Component …等都有什么区别?
⽤SpringBoot开发应⽤时,我们会⽤注解将对象交给Spring容器管理。这些注解包括:
@Component ,@Service, @Bean, @Controller ,@Repository
这些注解本质上,都是Spring标识,⽤来进⾏Bean的⾃动检测。标注这些注解的类会被Spring容器管理。
那为何要有这些分类,为何不使⽤⼀个注解就来搞定所有的⼯作?
⾸先这⼏个注解根据语义,⽤在不同的层⾯
@Componet ⼀般的组件
@Service是Service层组件
@Bean 这个要和@Configuration⼀块使⽤,后边再说
@Controller是⽤在SpringMVC控制层
@Repository是数据访问层
Spring这样设计,是因为,这些注解不光是要做⾃动检测。同时有不同的功能,⽐如@Repository注解,Spring会增加增强处理,进⾏相关的异常处理。@Controller的bean会处理⽹络请求相关逻辑。所
以你给所有的Bean都标注同⼀个注解,确实都会注⼊Spring容器,但是功能可能就会失效。⽽且随着Spring版本升级,可能会增加更多差异化处理。所以我们应该按照规范来注解。
再说到@Bean,我们知道Spring早期,还是通过xml配置Bean例如:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
xsi="/2001/XMLSchema-instance"context="/schema/context"
schemaLocation="/schema/beans
/schema/beans/spring-beans.xsd
/schema/context
/schema/context/spring-context.xsd">
<bean id="operations"class="com.howtodoinjava.spring.beans.Operations"></bean>
<bean id="employee"class="com.howtodoinjava.spring.beans.Employee"></bean>
</beans>
现在,你可以理解@Configuration注解的类就是⼀个xml配置⽂件,中间@Bean注解就是xml中的bean节点
@Configuration
public class BeanConfiguration{
@Bean
public Operations operation(){
return new Operations();
spring mvc和boot区别}
@Bean
public Employee employee(){
return new Employee();
}
}
这两种⽅式都是将@Bean注解返回值注⼊Spring容器。SpringBoot在启动时,会扫描@Configuration注解,进⾏注⼊。SpringBoot注⼊对象冲突如何解决?
好了,现在我们终于把想要的组件交给Spring容器管理。我们该如何使⽤?
我们可以⽤Spring上下⽂,获取需要的对象
public static void main(String[] args){
ApplicationContext application = SpringApplication.run(ConsumerApplication.class, args);
}
⼀般我们⽤@Autowire 注解,获取容器中的bean
@Autowire
private Employee employee;
有时我们在容器中需要注⼊⼀个类的多个实例,以满⾜需求。⽐如⼀个接⼝的实现类有两个,如果直接通过@Component注⼊容器,则会报错。如何区分?
@Component("bean01")
public class Bean01 implement AA{
}
@Component("bean02")
public class Bean02 implement AA{
}
没错,通过在注解中标识⼀个名称,来区分该对象的不同实例。
获取时:最终会初始化⼀个Bean01
@Autowire
@Qualifier("bean01")
private AA a;
这样有个问题,就是每次使⽤都需要显⽰声明@Qualifier来指定。有的场景下,我们可能想默认使⽤⼀个,其他情况再显式指定。这就涉及到@Primary
在注解时,标注了@Primary的Bean在没有指定的情况下,会默认加载。
⽐如:
@Component
@Primary
public class Bean01 implement AA{
}
@Component("bean02")
public class Bean02 implement AA{
}
使⽤时: 默认初始化的就是Bean01
@Autowire
private AA a;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论