一、javaBean和Bean的理解?
刚开始的时候总会把这俩个内容认为是查不多的,但是其实并不是这样的。Bean是存放于Spring IOC容器中的对象,所以称为Bean ,而JavaBean是一种特殊的JAVA类,javaBean类实例化出的对象称之为javaBean对象。它们的生命周期也是不一样的,Bean的生命周期由spring IOC容器来控制的,而javaBean是不受容器来控制的。所以,在 Spring 中,所有可以被 IOC容器 实例化并管理的 Java类 都可以称为 Bean。
二、Bean和spring的关系
图片和总结来源于:https://www.cnblogs.com/wuchanming/p/5426746.html
这是从网上来的一张图片,很好的表达了Spring和Bean的关系。
Bean的配置信息定义了Bean的实现和依赖关系,Spring IOC容器根据Bean的配置信息,在容器内部建立Bean注册表,在根据注册表的信息来实例化Bean,并建立依赖关系,然后这些Bean实现类,放在容器中的Bean的缓冲池中,供外部调用。
三、Bean的配置
- 基于xml配置
- 使用注解配置
- 使用java类提供Bean定义信息
3.1 基于xml配置
上面的图片很好的解释了,我们常见的spring项目的配置文件开头部分bean的代码解释。
①默认命名空间:它没有空间名,用于Spring Bean的定义;
②xsi命名空间:这个命名空间用于为每个文档中命名空间指定相应的Schema样式文件,是标准组织定义的标准命名空间;
③aop命名空间:这个命名空间是Spring配置AOP的命名空间,是用户自定义的命名空间。
命名空间的定义分为两个步骤:第一步指定命名空间的名称;第二步指定命名空间的Schema文档样式文件的位置,用空格或回车换行进行分分隔。
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- id是bean的名称,容器通过getBean(id)来查找bean,class是Bean的类名 -->
<bean id="city" class="com.maven.study.model.City"></bean>
</beans>
3.2使用注解来定义bean
采用基于xml配置bean,定义信息和实体类是分离的,而采用注解的方式,则是通过bean实体类的上标注注解实现的。
package com.maven.study.model.city;
import org.springframework.stereotype.Component;
/**
* 城市
* @author tsy
*
*/
@Component("city")
public class City {
....
}
使用@Component来注解实体类,他可以被spring容器识别,自动的将POJO转化成Bean。它于上面的基于xml配置是一样的。
除此之外,还有一些Bean的衍型注解:
- @Repository:用于对DAO实现类进行标注;
- @Service:用于对Service实现类进行标注;
- @Controller:用于对Controller实现类进行标注;
通过注解信息来启动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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
<context:component-scan base-package="com.maven.study.controller" />
<context:component-scan base-package="com.maven.study.service" />
<context:component-scan base-package="com.maven.study.dao" />
</beans>
3.3 基于java类提供Bean定义
使用@Configuration来定义Bean,然后通过@Bean相当于提供了一个Bean信息
package com.maven.study.model;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 下面代码就是通过java类提供bean定义来配置
* @Configurantion的标注,说明这个类是spring提供的bean的定义信息
* @Bean定义类的方法,它 的类型取决于该方法的返回类型,名称morning和方法名一样的,也可以通过@Bean("city") 来定义
*
* 可以用xml的方法来替换:
*
* <bean id="getCity" class="com.maven.study.model.City"/>
* <bean id="getProvince" class="com.maven.study.model.Province"/>
* <bean id="getAddress" class="com.maven.study.model.Address"
* p:getCity-ref="getCity" p:getProvince-ref="getProvince"/>
*
*/
@Configuration
public class Test {
@Bean
public Province getProvince(){
return new Province();
}
@Bean
public City getCity(){
return new City();
}
@Bean
public Address getAddress() {
Address address = new Address();
address.setCity(getCity());
address.setProvince(getProvince());
return address;
}
}
四、Bean的注入
1.1 xml的属性注入
package com.maven.study.model;
public class Address {
private City city;
private Province province;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
public Province getProvince() {
return province;
}
public void setProvince(Province province) {
this.province = province;
}
}
xml的配置:
<bean id="city" class="com.maven.study.model.City"/>
<bean id="province" class="com.maven.study.model.Province"/>
<bean class="com.maven.study.model.Address">
<property name="province" ref="province"></property>
<property name="city" ref="city"></property>
</bean>
1.2 构造方法注入
package com.maven.study.model;
public class Address {
private City city;
private Province province;
public Address(City city, Province province) {
this.city = city;
this.province = province;
}
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
public Province getProvince() {
return province;
}
public void setProvince(Province province) {
this.province = province;
}
}
xml配置:
<bean id="city" class="com.maven.study.model.City"/>
<bean id="province" class="com.maven.study.model.Province"/>
<bean class="com.maven.study.model.Address">
<constructor-arg ref="province"></constructor-arg>
<constructor-arg ref="city"></constructor-arg>
</bean>
1.3 工厂方法注入
很多工厂类都是静态的,这意味着用户在无须创建工厂类实例的情况下就可以调用工厂类方法,因此,静态工厂方法比非静态工厂方法的调用更加方便。
2.1 使用@Autowired进行自动注入
package com.maven.study.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.maven.study.dao.CityDao;
import com.maven.study.model.City;
import com.maven.study.service.CityService;
@Service("cityService")
public class CityServiceImpl implements CityService {
@Autowired(required=false)
@Qualifier("dao")
private CityDao dao;
@Override
public List<City> selectCity() {
return dao.selectCity();
}
}
如果标注的这个bean找不到,当启动spring的时候就会报出NoSuchBeanDefinitionException的异常的,如果加上required=false意思就是找不到这个bean,程序也正常进行。一般默认是true。Qualifie("xxx")这个注解的意思就是告诉IOC容器程序具体的要找的哪个bean,假如有一个bean的名是dao,另一个是Dao,加上这个就表示程序具体要找的dao的bean。
2.2 @Resource和@Inject注解
package com.maven.study.model;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
@Component
public class Address {
private City city;
private Province province;
public Address(){}
public City getCity() {
return city;
}
@Resource("city")
public void setCity(City city) {
this.city = city;
}
public Province getProvince() {
return province;
}
public void setProvince(Province province) {
this.province = province;
}
}
@Resource的注解是通过名称来注入Bean,而@Autowired的注入是通过类型注入的。@Inject和@Autowired是一样的,只不过@Inject是没有required属性的。现在可以看出@Autowired的功能要强大的多,所以基本上的项目的都是用@Autowired来注入的。
2.3 使@Autowired和@Resource的xml的配置
<!-- 为了使用Autowired标签,我们必须在这里配置一个bean的后置处理器 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/
<!-- 为了使用@Resource标签,这里必须配置一个后置处理器 -->
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<!-- 在xml配置文件中使用context:annotation-config -->
<context:annotation-config />
<!-- 扫描包 -->
<context:component-scan base-package="xxx.xxxx.xxxx"/>