6.4 Bean的作用域
类别 | 说明 |
---|---|
singleton | 在Spring IoC容器中仅存在一个Bean实例,Bean以单例方式存在 |
prototype | 每次从容器中调用Bean时,都返回一个新的实例 |
request | 每次http请求都会返回一个新的实例,该作用域仅适用于WebApplicationContext环境 |
session | 同一个Http Session共用一个Bean,不同session使用不同的Bean,该作用域仅适用于WebApplicationContext环境 |
global-session | 该属性仅用于HTTP Session,同session作用域不同的是,所有的Session共享一个Bean实例。 |
- 单例模式(Spring默认机制)
<bean id="address" class="pojo.Address" c:address="China" scope="singleton"></bean>
2.原型模式,每次从容器中获取都会得到一个新的对象
<bean id="address" class="pojo.Address" c:address="China" scope="prototype"></bean>
3.其他模式只能在web开发中使用
7 bean的自动装配
自动装配是Spring满足bean依赖的一种方式
Spring会在上下文中自动寻找,并自动给bean装配属性
在Spring中有3种装配方式
1.在xml中显式的配置
2.在java中显式的配置
3.隐式的自动装配
实体类
public class Cat {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Dog {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Person {
private Cat cat;
private Dog dog;
private String name;
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
未使用自动装配,注入方式
<bean id="cat" class="Cat"></bean>
<bean id="dog" class="Dog"></bean>
<bean id="person" class="Person">
<property name="name" value="小明"></property>
<property name="cat" ref="cat"></property>
<property name="dog" ref="dog"></property>
</bean>
7.2 ByName自动装配
<bean id="cat" class="Cat"></bean>
<bean id="dog" class="Dog"></bean>
<bean id="person" class="Person" autowire="byName">
<property name="name" value="小明"></property>
</bean>
ByName会自动在容器上下文查找,和自己对象set方法后面的值对应的bean id
7.3 ByType自动装配
<bean class="Cat"></bean>
<bean class="Dog"></bean>
<bean id="person" class="Person" autowire="byType">
<property name="name" value="小明"></property>
</bean>
ByType会自动在容器上下文查找,和自己对象属性类型相同的bean
总结:byName的时候,需要保证所有bean的id值唯一,并且这个bean需要和自动注入的属性的set方法值一致
byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性类型一致
7.4 使用注解实现自动装配
jdk1.5支持注解,spring2.5开始支持注解
使用注解须知
- 导入约束 context约束
- 配置注解的支持
<context:annotation-config/>
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
@Autowired
直接在属性上使用即可!也可以在set方式上使用
使用Autowried可以不用编写set方法,前提是这个自动装配的属性在IoC容器(Spring)中存在
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解支持-->
<context:annotation-config/>
<bean id="cat" class="Cat"></bean>
<bean id="dog" class="Dog"></bean>
<bean id="person" class="Person"></bean>
</beans>
import org.springframework.beans.factory.annotation.Autowired;
public class Person {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
private String name;
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Nullable字段标记了这个注解,说明这个字段可以为null
Autowired的required属性为false,说明这个属性可以为null,否则不能为空
@Autowired(required = false)
如果@Autowired自动装配的环境比较复杂。自动装配无法通过一个注解@Autowired完成的时候,我们可以使用@Qualifier(value=“xx”)去配置@Autowired的使用,指定唯一一个bean注入对象
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Person {
@Autowired
@Qualifier("cat")
private Cat cat;
@Autowired
@Qualifier("dog")
private Dog dog;
private String name;
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Resource注解
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import javax.annotation.Resource;
public class Person {
@Resource(name = "cat")
private Cat cat;
@Resource(name="dog")
private Dog dog;
private String name;
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Resource和@Autowried的区别
都是用来自动装配的,都可以放在属性字段上
@Autowried通过byType方式实现,而且要求这个对象必须存在,如果多个同类型则再进行byName
@Resource默认通过byName方式实现,如果找不到名字,通过byType方式实现
执行顺序不同:@Autowried通过byType方式实现,@Resource默认通过byName方式实现
8 使用注解开发
在Spring4之后要使用注解开发,必须要保证aop的包导入了
需要导入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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--指定要扫描的包,这个包下的注解就会生效-->
<!--扫描指定包下,标有@Componet的类,注册成bean-->
<context:component-scan base-package="pojo"/>
<context:annotation-config/>
</beans>
package pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//@Compent的作用等价于<bean id="user" class="pojo.User">
@Component
public class User {
//等价于<property name="name" value="小明"/>
@Value("小明")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
测试代码
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pojo.User;
public class Test {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
User user=context.getBean("user",User.class);
System.out.println(user.getName());
}
}
@Component:组件,放在类上,说明这个类被Spring管理(bean)
@Component有几个衍生的注解,我们在web开发中会按照mvc三层架构开发!
dao [@Repository]
service [@Service]
controller [@Controller]
这四个注解功能都是一样的,都是代表某个类注册到Spring中,装配bean
自动装配
@Autowired 通过类型,名字
如果@Autowried唯一自动装配属性,使用@Qualifier(value=“xx”)辅助
@Resource 通过名字,类型
package pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
//@Compent的作用等价于<bean id="user" class="pojo.User">
@Component
@Scope("prototype")
public class User {
//等价于<property name="name" value="小明"/>
@Value("小明")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
小结
xml与注解:
- xml更加万能,适用于任何场合,维护简单方便
- 注解 不是自己的类使用不了,维护相对复杂
xml与注解最佳实践
- xml用来管理bean
- 注解只负责完成属性的注入
- 我们在使用的过程中,只需要注意一个问题:必须让注解生效,开启注解支持
<!--指定要扫描的包,这个包下的注解就会生效-->
<!--扫描指定包下,标有@Componet的类,注册成bean-->
<context:component-scan base-package="pojo"/>
<context:annotation-config/>
9 使用Java的方式配置Spring
package pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class User {
@Value("张三")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import pojo.User;
@Configuration
@ComponentScan("pojo")
public class Config {
//注册一个bean,相当于xml中的bean标签
//方法的名字,相当于bean标签的id属性
//方法的返回值,相当于bean标签的class属性
@Bean
public User getUser()
{
return new User();
}
}
import config.Config;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import pojo.User;
public class Test {
public static void main(String[] args) {
//如果完全使用配置类的方式实现,需要通过配置类的class对象加载
ApplicationContext context=new AnnotationConfigApplicationContext(Config.class);
User user=context.getBean("getUser",User.class);
System.out.println(user.getName());
}
}
纯java的配置在SpringBoot中随处可见