一:Eclipse安装Spring插件
安装Spring插件不是必需的,这样做只是省去了拷贝spring的xml配置文件的dtd约束的环节,如果没有安装spring插件可以去spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html文件中拷贝约束,并手动配置本地dtd。
1、访问http://spring.io/tools/sts/all网页,下载和所用Eclipse版本对应Spring Tool Suite离线工具,由于这里使用Eclipse 4.7.2,所以这里下载springsource-tool-suite-3.9.2.RELEASE-e4.7.2-updatesite.zip
2、打开Eclipse,点击“Help”菜单,出现下图:
3、点击“Install New Software…”,出现下图:
4、点击“Add…”按钮,出现下图:
5、点击“Archive…”按钮,然后选择刚下载的Spring Tool Suite Eclipse 插件,出现下图:
6、点击“OK”按钮,出现下图:
7、选中上图四个“XXX/Spring IDE”选项,不要勾选上图蓝框复选框,点击“Next>”,出现下图:
8、点击“Next>”,出现下图:
9、点击“Next>”,出现下图:
10、选择“I accept the terms of the license agreement”,然后点击“Finish”,至此开始向Eclipse中安装“Spring Tool Suite Eclipse”插件,过一会儿出现下图:
11、点击“Install anyway”按钮,过一会儿出现下图后点击“Restart Now”:
二:初始SpringIOC
1、IOC(Inversion of Control,控制反转):通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体(Spring)将其所依赖的对象的引用传递给它,也可以说是依赖被注入到对象中。
2、作用:可以用来减低计算机代码之间的耦合度。
3、如何理解SpringIOC可以用来减低计算机代码之间的耦合度?
- a.传统方式的对象由开发者直接new一个类:例如,原始社会人的移动就是步行,move唯一的含义就是walk。但是日后出现了骑马的方式,用move来表示两种移动方式显然不合理。
Move move = new Move();
- b.为解决上述问题,可以将Move声明为接口,其最大的好处就是可以利用多态:但是这样做的话,日后修改交通方式就需要在程序中修改实现类。(接口和实现类出现了耦合)
Move move = new walk();
- c.为了实现接口与实现类的解耦,可以用工厂模式:这样做虽然做到了接口与实现类的解耦,但是又出现了接口与工厂类的耦合,修改交通方式就需要在工厂类中修改相应的方法。
Move move = MoveFactory.getMove();
- d.为了完全解决程序的耦合现象,就用到了Spring的IOC:Spring的IOC利用工厂、反射和配置文件实现了程序的解耦,修改交通方式只需在配置文件中修改即可。
4、Spring的架构体系:
三、创建Spring项目认识IOC
1、创建一个普通Java的工程,名叫“spring”,顺便拷贝个lo4j.properties;
2、向工程中添加如下jar包:
-
a、下载Spring相关jar包:
-
b、创建lib文件夹,所需jar包可以通过Spring的架构图了解:Beans、Core、Context、SpEl,但是Spring需要依赖一个日志输出规范的jar包,并且日志输出需要用到logj,因此所需jar包如下:
-
c、由于是Java工程,所以为了使这些jar包起作用需要先选择这些jar包——>鼠标右键点击Build Path——>Add to Build Path;如果是Java Web工程只需将这些jar包拷贝到WEB-INF中lib文件夹即可;
3、新建一个包“cn.jingpengchong.vo”,在其中新建一个接口Move和两个实现类MoveWalk和MoveRide:
package cn.jingpengchong.vo;
public interface Move {
void move();
}
package cn.jingpengchong.vo;
public class MoveWalk implements Move {
@Override
public void move() {
System.out.println("步行。。。");
}
}
package cn.jingpengchong.vo;
public class MoveRide implements Move {
@Override
public void move() {
System.out.println("骑马。。。");
}
}
4、创建Spring XML文件:
- a、选中src目录——>鼠标右键,选中并点击“Other…”项——>找到并打开“Spring”节点,出现下图:
- b、选择“Spring Bean Configuration File”子节点,点击“Next>”按钮,出现下图:
- c、在“File name”文本框输入配置文件的文件名(这里为applicationContext.xml),点击“Next>”按钮,出现下图:
5、配置“applicationContext.xml”文件:
- a、<bean></bean>方式配置:缺点是大项目中类太多,一个一个配置很麻烦
<bean name="move" class="cn.jingpengchong.vo.MoveWalk" lazy-init="default" scope="prototype"/>
- 说明:
- id:用于ApplicationContext对象用getBean(“id值”)方法获取class属性值中声明的类对象,id值只能有一个,并且id不能重复;
- name:用于ApplicationContext对象用getBean(“name值”)方法获取class属性值中声明的类对象,name值可以有多个,并且name可以重复;
- class:声明该类的完整路径;
- lazy-init:懒加载
- 默认default(false),容器加载的时候就创建对象;
- true,第一次使用的时候创建对象
- scope:该对象的适用范围。
- singleton:只创建一个,项目内都可以使用;
- prototype:每次获取都重新创建一个对象,每次获取的对象都不一样;
- session:在当前session中只创建一个,每次获取的都是一个对象;
- request:在每次请求中都会创建一个对象,每次请求获取的对象都不一样;
- b、扫描方式配置:
<context:component-scan base-package="cn.jingpengchong.vo"></context:component-scan>
- 说明:这种方式需要以下两个步骤:
- 导jar包:spring-aop-4.3.10.RELEASE.jar;
- 扫描的类上面要加注解"@Controller"、"@Service"或"@Component"其中之一,“base-package”属性值声明的包下面所有加了这三种注解的都会被扫描到。
6、创建包“cn.jingpengchong.test”,编写测试代码“Test01.java”文件:
- a、加载IOC容器:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
- b、获取“applicationContext.xml”文件中配置的类对象:
- 如果是<bean></bean>方式配置:
//方式一:获得的是上转型对象 Move move = (Move)context.getBean("move"); //方式二:获得的是非上转型对象 Move move = context.getBean(Move.class);
- 如果是扫描方式配置:
//只能用这种方式获取,因为配置的类对象没有id和name Move move = context.getBean(Move.class);
- 如果是<bean></bean>方式配置:
“Test01.java”文件:
package cn.jingpengchong.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.jingpengchong.vo.Move;
public class Test01 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Move move = (Move) context.getBean("move");
move.move();
}
}
运行结果如下:
如果我们想更换交通方式只需要将:
<bean name="move" class="cn.jingpengchong.vo.MoveWalk" lazy-init="default" scope="prototype"/>
更换为:
<bean name="move" class="cn.jingpengchong.vo.MoveRide" lazy-init="default" scope="prototype"/>
即可,再次运行测试代码,结果如下:
四、IOC和DI的区别:
1、IOC(控制反转):将类的实例化交给Spring管理;
2、DI(依赖注入):Spring为被其管理并实例化的类的属性赋值。常见的面向对象的关系有继承、聚合与依赖等。
注入方式有:
- properties标签或p名称空间调用类的set方法注入;
- constructor-arg标签调用类的有参构造方法注入。
注入的数据类型有:
- 基本数据类型和String类型;
- 其他类类型;
- 数组与集合;
- SpEl表达式:#{…};
- properties资源文件:${…};
例:properties标签方式的属性注入
改造上面的MoveRide类:
package cn.jingpengchong.vo;
public class MoveRide implements Move {
private String horse;
public void setHorse(String horse) {
this.horse = horse;
}
@Override
public void move() {
System.out.println("骑马。。。"+horse);
}
}
修改上面的配置文件:
<bean id="move" class="cn.jingpengchong.vo.MoveRide" lazy-init="default" scope="prototype">
<property name="horse" value="白龙马"/>
</bean>
运行测试类结果如下:
五、Spring的工厂类接口:ApplicationContext 和BeanFactory的区别:
1、ApplicationContext 继承了BeanFactory,因此比BeanFactory有更多的功能;
2、ApplicationContext在加载配置文件时就实例化对象,而BeanFactory在getBean()方法执行时才实例化对象。
3、ApplicationContext有两个实现类:
- ClassPathXmlApplicationContext:加载类路径下的配置文件;
- FileSystemXmlApplicationContext:加载文件系统下的配置文件。