bean的生命周期
- Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载、实例化Bean,并建立Bean和Bean的依赖关系,最后将这些准备就绪的Bean放到Bean缓存池中,以供外层的应用程序进行调用。
3个装配方式
- 基于Java类的配置方式
- 基于XML的配置方式
- 基于注解的配置方式
1.基于Java类的配置方式
基于Java类定义Bean配置元数据,其实就是通过Java类定义Spring配置元数据,且直接消除XML配置文件。
1.1要点:
- 必须要两个注解:
- @Configuration :代替了xml配置.表明该类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。
- @Bean : 告诉Spring,这个方法将会返回一个对象。一般用在构造器和Setter方法上
- 只需要这个两个注解,就可以完成bean的装配过程了。
- 非必须的注解:
- @import :用来引入别的类里面同样有@Configuration标签的类。
- @importResource : 用来引入xml配置,实现xml配置方式和java类配置方式共存。
1.2例子
- 代码结构
- Configuration 包:用来放Java类的配置。其实其作用就是跟xml配置一样的。所以此包下的类是Java类配置方式的核心
- Entity 包:用来放bean
- test 包: 测试
- 代码
- Configuration 包下的EntityConfig类:
@Configuration //表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源
public class EntityConfig {
@Bean
public UserBean user(){
return new UserBean( student()); //有参构造
}
@Bean
public StudentBean student(){
return new StudentBean();
}
}
- Entity 包 UserBean类和StudentBean类:
public class UserBean {
private StudentBean studentBean;
public UserBean(){}
public UserBean(StudentBean studentBean){
this.studentBean=studentBean;
}
@Override
public String toString() {
return "this is UserBean";
}
public StudentBean getStudent(){
return studentBean;
}
}
public class StudentBean {
private String name;
private int age;
@Override
public String toString() {
return "this is StudentBean";
}
}
- test 包
@Test
public void test(){
ApplicationContext ctx=
new AnnotationConfigApplicationContext(EntityConfig.class); //应用上下问
UserBean userBean=ctx.getBean(UserBean.class);
StudentBean student = userBean.getStudent(); //从userBean里,看是否获得studenBean
System.out.println(student.toString());
}
1.3基于Java类的配置主要使用场景:
对于实例化Bean的逻辑比较复杂,则比较适合用基于Java类配置的方式
2.基于XML配置
其实可从基于java类配置方式去考虑,在Java类配置方式中,需要的两个注解@Configuration 和@Bean 转化成xml配置文件里说明。这样的话java的配置类也可以不要了。
2.1要点
2.2 例子
- Entity类:跟上面类一样,不需要该。
- xml配置:
<?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-2.5.xsd">
<bean id="studentBean" class="cn.Entity.StudentBean"/>
<bean id="userBean" class="cn.Entity.UserBean">
//在userBean类里面注入StudentBean 类,如果没有这条会出现
NullPointerException异常
<property name="studentBean" ref="studentBean"/>
// name="" 是userBean 的属性名称。(需要setter方法)
// ref="" 是上面studentBean类注入的id。
</bean>
</beans>
- test类
@Test
public void testUserBean(){
ApplicationContext ctx=
new ClassPathXmlApplicationContext("spring.xml"); //配置文件的绝对路径
if (ctx!=null){
UserBean user = (UserBean) ctx.getBean(UserBean.class);
System.out.println(user.getStudent());
}
}
- 使用场景:
- 第三方类库,如DataSource、JdbcTemplate等;
- 命名空间,如aop、context等;
3.自动化装配bean
可以对比前面两种方法的变化,可以知道配置方法上的不同了。
- 相对于基于xml配置方法来说,不需要在xml里面配置注入bean的信息,而换成注解注入。
- 而相对与基于java配置方法来说,不需要在配置类中创建对象的方法,只需要在需要注入的地方,用注解就可以了
3.1要点
- 从两个角度来实现自动化装配:
- 组件扫描:Spring会自动发现应用上下文中所创建的bean。(需要在xml里面配置,或者用注解)
- 自动装配:Spring自动满足bean之间的依赖。(需要用注解)
3.2例子
- 用@configuration来装配bean
- 用到的注解
- @Configuration :代替了xml配置.表明该类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。
- @ComponentScan:启动组件扫描。(如果没有设定范围,默认该包下)
- @Autowired :自动注入。用在类下对象的注入
- @Compoent : 表明该类会作为组件类,并告知Spring要为该类建立bean。
- @RunWith(SpringJUnit4ClassRunner,class):在测试开始的时候自动创建Spring的应用上下文
- @ContextConfiguration(class=xxxx) :加载配置,在这里是Config.class
- 用到的注解
很奇怪,如果不用@ContextConfiguration(class=xxxx) 这个加载配置,是扫描不到我测试类下面的@Autowired 注解。也就是我用正规创建上下文方法创建的话,test类下的对象是null的。 有待解决
- 代码结构
- Config类:用来装配Spring规则。具有@Configuration和@ComponentScan注解
- StudentBean类和UserBean
- test类
- 例子
- Config类
@Configuration
@ComponentScan(basePackages = {"cn.Entity"})
public class Config { //不需像基于java配置一样,用方法返回new 对象。
}
- SutdentBean和UserBean类
@Component
public class StudentBean {
private String name;
private int age;
@Override
public String toString() {
return "this is StudentBean";
}
}
***********************************************************************
@Component
public class UserBean {
private StudentBean studentBean;
public UserBean(){}
@Autowired
public UserBean(StudentBean studentBean){
this.studentBean=studentBean;
}
@Override
public String toString() {
return "this is UserBean";
}
public StudentBean getStudent(){
return studentBean;
}
public StudentBean getStudentBean() {
return studentBean;
}
}
- test类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Config.class)
public class UserBeanTest extends TestCase {
@Autowired
private UserBean userBean;
@Test
public void testUserBean(){
System.out.println(userBean.getStudent());
System.out.println(userBean);
}
}
- 用xml配置文件来装配bean
只是把上面的Config类,用xml替换掉。其实只是用xml文档写一个扫描语句- spring.xml文档
<?xml version="1.0" encoding="UTF-8"?> <beans //省去很多约束 <context:component-scan base-package="cn.Entity"/> </beans>
- StudentBean类和UserBean类没变
- Test类
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"/spring.xml"}) //加载xml配置 public class UserBeanTest extends TestCase { @Autowired private UserBean userBean; @Test public void testUserBean(){ System.out.println(userBean.getStudent()); System.out.println(userBean); } }
- spring.xml文档
- 使用场景:Bean的实现类是当前项目开发的,可直接在Java类中使用注解配置
4.总结
- 3个配置方式其实都很简单,在开发过程中,都是推荐使用xml配置和自动化装配。
- 不同配置方式比较