在上两篇的博文中,分别对spring框架中的两个很重要的概念DI(Dependency Injection)和AOP(Aspect-Oriented programming)做了介绍,或许不那么完美,但那也是我对这两个概念的理解,然后我这几天我发现有的东西还是要用一下才能真正的理解,所以接下来我们来介绍一个怎么去使用DI,后面也会谈到AOP,慢慢来。
1.在谈到怎么去装配Bean之前,我觉得有必要明白两个概念,一个是Container,还有一个就是ApplicationContext。
(1)container:翻译过来的意思就是容器,看起来好像很简单,但是在spring中他到底扮演的是什么角色呢?
container的作用其实就是负责去管理对象的生命周期,比如对象的created,wiring,还有live(活动周期)。
(2)ApplicationContext:翻译过来就是应用的上下文。说到底他到底有什么用呢?
我觉得这个理解起来会有点费劲,其实可以简单的理解为一个container的操作工具。就是操作container里面的对象的,也即是一个个Bean。或者这样说,理解也难,那么我们先看看他的前身吧(大概的说为前身)BeanFactory,正如字面上看到的先直译过来就是Bean工厂,而ApplicationContext就是从他的基础上扩展过来的,这样会不会更好的理解呢?BeanFactory为我们提供了基本的DI(依赖注入)的可能性保障。前期大家可以看看下面这图来记:
2.每一个Bean的生命周期
我觉得这个部分的内容还是很重要,在这里我就不展开来讲了,因为边幅比较长,讲起来也很难明白,最好就是看看spring中关于Bean的源码。现在可以初略的看做怎么去读取XML文档里面的数据,然后利用java的反射机制来调用类的方法吧。
3.进入正题,怎么去装配Bean,或者说定义一个Bean呢?
方式有两种,也可以说有三种:
(1)基于注解的方式,注解也分为java-based configuration 和 spring本身提供的注解
(2)基于Xml的方式,就是写进xml文件里面去
4.在怎么去定义一个bean之前我觉得有必要明白怎么去获取我们所定义的bean。
我要说的其实本质就是怎么去获取一个ApplicationContext对象,如下:
ApplicationContext ctx = new ....................-------------见下面:
(1)基于java-based configuration的(注解的,以后基于注解的我都说成是注解)(常用)
ApplicationContext ctx = new AnnotationConfigApplicationContext();---------括号传入我们所定义的class类,多个可以用数组的方式
(2)基于注解的Web形式
ApplicationContext ctx= new AnnotationConfigWebApplication();------------括号传入我们所定义的class类,多个可以用数组的方式
(3)基于Xml的,该xml文件位于我们的classpath(常用)
ApplicationContext ctx = new ClassPathXMLApplicationContext();----------传入我们所写的xml文件,要注意的是路径位于classpath
(4)基于xml的,该xml文件位于我们的文件系统,或者说是操作系统中的盘
ApplicationContext ctx = new FileSystemXmlApplicationContext();-----------------传入我们所写的xml文件,要注意的是路径位于文件系统
(5)基于xml,该文件是通过Web来获取到的
ApplicationContext ctx = new XMLWebApplicationContext();-----------------传入我们所写的xml文件,要注意的是路径web
5.知道了怎么去获取,我们就开始去Wiring bean吧。
(1)先说基于注解的(因为我觉得注解的是大势所趋,spring boot就是很好的例子,配置xml太繁琐,后面也会谈到)
首先先说一下,我们要用到的注解有:
@Configuration ---------------声明该类为配置类
@Componnet ----------------声明该类为一个组件类,我觉得这个还是记他的英文比较好
@ComponentScan ----------声明要扫描的地方
@Bean --------------------------声明一个Bean
@Autowired -------------------自动装配Bean
了解了我们要用到的注解,那么我们通过一个简单的例子来说明一下:
(2)导入spring的jar包,(ps:博主使用的是4.3的)---------------这部分请自己导入
(3)创建一个Say Hello的接口:
package com.yqy.CSDN.Spring;
public interface SayHello {
void sayHello();
}
(4)创建接口的实现类:
package com.yqy.CSDN.Spring;
import org.springframework.stereotype.Component;
@Component
public class SayHelloWorld implements SayHello{
@Override
public void sayHello() {
System.out.println("Say Hello World");
}
}
(5)用注解的方式实现定义一个Bean
package com.yqy.CSDN.Spring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackageClasses={SayHelloWorld.class})
public class BeanConfig {
@Bean
public SayHello getSayHelloWorld(){
return new SayHelloWorld();
}
}
(6)测试一下:
package com.yqy.CSDN.Spring;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class BeanConfigTest {
@Test
public void test() {
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanConfig.class);
SayHello s = (SayHello) ctx.getBean("getSayHelloWorld");
s.sayHello();
}
}
结果如下:
Say Hello World
这样我们就定义好一个Bean 了,对比xml的方式是不是很简单呢?这里需要注意的一点就是@Bean如果你没有指定名的话,它的ID默认的就是方法的名。
6.我们看看XML是怎么实现同样的功能的把:
(1)配置xml文件:applicationContext.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<pre name="code" class="java">
<span> <context:component-scan base-package="test"></context:component-scan></span>
package com.yqy.CSDN.Spring;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanConfigTest {
@Test
public void test() {
ApplicationContext ctx = <span style="color:#ff0000;">new ClassPathXmlApplicationContext("applicationContext.xml");</span>
SayHello s = (SayHello) ctx.getBean("SayHelloWorld");
s.sayHello();
}
}
7.总结:
虽然在这个小例子很难看出注解的优势,但是当你要配置很多个Bean的时候呢?我觉得光是配置xml就够我们吃的了。所以我建议还是用注解的方式。
后面我会介绍更过的注解的方式,到时候你会发现就是一个字爽!请继续关注我的博文。