Bean
之前的博客:
项目需要的配置依赖: link.
IoC部分: link.
Bean的作用域
- Singleton(单例模式): 每个IoC 容器仅有一个单实例,是默认方式,该 Bean 是在容器被创建时即被装配好了。
<bean id="user2" class="com.zmqcode.User.UserT" c:age="2" c:name="zmq" scope="singleton"/>
System.out.println(user==user2);//true
- Prototype(原型模式):每次从容器中get时都会产生一个新的对象,Bean 实例是在代码中使用该 Bean 实例时才进行装配的。
<bean id="user2" class="com.zmqcode.User.UserT" c:age="2" c:name="zmq" scope="prototype"/>
System.out.println(user==user2);//false
- 其余的方式:
Request: 每次请求都会创建一个实例
Session: 在一个会话周期内只有一个实例
Appilcation: 在一个 ServletContext 中只有一个实例
Websocket: 在一个 Websocket 只有一个实例
只会在Web开发中使用。
Bean的自动装配
Spring会在上下文中自动寻找,并给bean装配属性。在Spring中有三种装配的方式:
- 在xml中显式的配置(就像是之前的代码)
- 在java中显式的配置
- 隐式的自动装配【重要】
隐式的自动装配
- byName
会在容器上下文中自动寻找, bean id要对应被装配类中属性的名称,并且开头要小写。(也就是set后面的名字)
<bean id="cat" class="com.zmqcode.autowired.Cat"/>
<bean id="dog" class="com.zmqcode.autowired.Dog"/>
<bean id="person" class="com.zmqcode.autowired.Person" autowire="byName">
<property name="name" value="zmq"/>
<!--这两行就可以省略了-->
<!--<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>-->
</bean>
弊端: 必须保证对象名相同才可以,而且bean id要唯一。
- byType
会在容器上下文中自动寻找, bean id要对应被装配类中属性的类型,并且开头要小写。(也就是set后面的类型)
<!--id名可以省略-->
<bean class="com.zmqcode.autowired.Cat"/>
<bean class="com.zmqcode.autowired.Dog"/>
<bean id="person" class="com.zmqcode.autowired.Person" autowire="byType">
<property name="name" value="zmq"/>
</bean>
优点: id名可以省略
弊端: 只能装配全局唯一的类型,class唯一,如果传参有两个相同的类型,使用byType不能成功
- 使用注解实现自动装配
- 导入约束:context约束
- 配置注解的支持:context
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
使用注解开发
在Spring4之后,使用注解开发,必须要保证aop包导入了。还要配置context约束(上一个代码片中的内容)。
注解介绍
@Autowired
- 可以直接在属性上使用,此时不需要写set方法也可以实现注入
@Autowired
private Cat cat;
- 可以直接在set方法上使用
@Autowired
public void setCat(Cat cat) {
this.cat = cat;
}
@Autowired默认是按照先byType,class不唯一的话再去byName
@Qualifier+@Autowired
若此时类型不唯一,id名也不匹配,也就是自动装配的环境比较复杂,没有办法使用使用@Autowired单独完成,可以用 @Qualifier(value=“xxx”) 进行配置,显式的指定bean对象。
@Autowired
@Qualifier(value = "dog3")
private Dog dog;
@Resource
这个注解在jdk11中已经被移除了。
@Resource默认按照byName的方式实现,找不到再用byType。 @Resource和@Autowired的实现是类似的。区别就是 @Resource(value=“xxx”)可以这样进行配置,相当于@Qualifier+@Autowired。
@Component+ @Value
- 在配置文件中添加这句,可以指定多个包,分隔符可以使用逗号(,)分号(;)还可以使用空格。
<!--指定要扫描的包,这个包下的注解就会生效-->
<context:component-scan base-package="com.zmqcode.autowired"/>
<!--此时不需要这一句了-->
<context:annotation-config/>
**context:annotation-config/**这句就不用加了。
- @Component在类上指定,不指定对象的属性, bean的id是类名的首字母小写。如果要指定对象中的属性,通过 @Value实现,指定要注入的值。使用该注解完成属性注入时,类中无需setter。当然,若属性有 setter,则也可将注解加到setter上。
@Component
//等价于<bean id="user" class="com.zmqcode.develop.dao.User"/>
public class User {
@Value("zmq2")
//等价于<property name="name" value="zmq2"/>
public String name;
}
- @Component衍生注解:
➢ @Repository 用于对 DAO 实现类进行注解
➢ @Service 用于对 Service 实现类进行注解
➢ @Controller 用于对 Controller 实现类进行注解
注解设置作用域
@Scope
可以使用注解去指定bean的作用域
@Scope("prototype")