一、概述
spring的作用是优化对象创建的过程(IOC,Inversion of Control,控制反转),以及处理对象的依赖关系(DI,Dependency Injection,依赖注入)。
1. 控制反转
class UserAction{
//自己需要使用的对象,自己不创建
private IUserService userService;
//提供public的setter方法,交给别人(外部容器)创建
public IUserService setUserService(IUserService userService){
this.userService = userService;
}
}
2. 依赖注入
先有控制反转,后有依赖注入:通过控制反转创建完的对象,通过依赖注入确定对象之间的关系
class UserAction{
private IUserService userService;
//同时也是在处理对象关系
public IUserService setUserService(IUserService userService){
this.userService = userService;
}
}
3. AOP(Aspect Oriented Programming)面向切面编程
切面:由重复代码构成的类。通常存在于事物、日志以及权限处理中。
spring是一种非侵入式设计框架,对现有的类的结构没有影响,不需要实现或者继承某些特定的类,不用时可以卸载或者更换框架。(例如,struts就需要实现ActionSupport类来完成校验等特定功能,是侵入式框架;而hibernate是非侵入式的框架,只是多了映射文件,将现有的类及其关系映射到关系型数据库)
二、Spring框架开发HelloWorld
Spring提供了一站式解决方案
- Core 核心功能:IOC容器,创建对象,处理依赖关系
- Web 与Struts整合;spring MVC模式
- DAO JdbcTemplate类似DBUtils
- ORM 与Hibernate整合;或者封装hibernate
- AOP 难点
开发步骤
1)引入jar包
为了不用每次都引入jar包,可以将所有使用的jar包添加到自己建立的User Library中:新建自己的spring-core用户库,以后每次都引入即可。
需要使用的5个核心jar包:
commons-logging-1.1.3.jar
spring-beans-3.2.5.RELEASE.jar
spring-context-3.2.5.RELEASE.jar
spring-core-3.2.5.RELEASE.jar
spring-expression-3.2.5.RELEASE.jar
2)核心配置
- applicationContext.xml / bean.xml
- 约束文件
3)开发Bean
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--id用于标记,实际创建的对象由IOC容器通过反射指定的class="com.cityu.hello.User"创建-->
<bean id="springUser" class="com.cityu.hello.User"></bean>
</beans>
Test代码获取对象
方式一:
public class App {
@SuppressWarnings("deprecation")
@Test
public void testIOC() throws Exception {
//创建对象的过程交给spring
//User user = new User();
//1. 加载配置资源(路径,如果配置文件放在src目录下,可以只写文件名)
Resource rs = new ClassPathResource("com/cityu/hello/applicationContext.xml");
//2. 获取bean工厂类,IOC容器=工厂类+applicationContext.xml
BeanFactory factory = new XmlBeanFactory(rs);
//3. 使用工厂创建配置文件中id属性指定的对象
User springUser = (User) factory.getBean("springUser");
System.out.println(springUser);
}
}
方式二
@Test
public void testAc() throws Exception {
//获取IOC容器对象
ApplicationContext ac= new ClassPathXmlApplicationContext("com/cityu/hello/applicationContext.xml");
//从容器中获取对象
User user = (User) ac.getBean("springUser");
System.out.println(user);
}
三、对象创建细节
1. 对象数量
IOC容器默认创建单例对象,默认scope=”singleton”;适合service/dao/工具类
但是对于Action,通常需要创建多个scope=”prototype”;
2. 什么时候创建对象?
scope=”singleton”时,容器初始化之前就已经创建对象,整个项目中只维护这一个对象。
scope=”prototype”时,容器初始化之后,需要使用该对象(例如用户访问Action时)创建对象。
3. 懒加载
只对单例有效
指定lazy-init=”false”时,不延迟创建,容器初始化时创建;
指定lazy-init=”true”时,延迟创建,使用时创建;
4. 对象初始化/销毁
init-method=”init()”需要写在Bean中,紧接对象创建之后执行;
destroy-method=”destroy()”,需要使用容器对象来销毁;销毁容器后,紧接着执行对象销毁方法;
Test
public void testAc() throws Exception {
//获取IOC容器对象,如果想后面销毁容器,两个办法
//1. 使用实现类,而不是ApplicationContext接口
//2. destroy时强转((AbstractApplicationContext) ac).destroy();
ClassPathXmlApplicationContext ac= new ClassPathXmlApplicationContext("com/cityu/hello/applicationContext.xml");
System.out.println("!!!容器创建!!!!");
//从容器中获取对象
User user = (User) ac.getBean("springUser");
System.out.println(user);
ac.destroy();
}
四、Spring IOC容器
创建对象的四种方法
1. 无参数构造器
<bean id="springUser" class="com.cityu.b_createObj.User"></bean>
2. 带参数构造器
<bean id="user2" class="com.cityu.b_createObj.User">
<constructor-arg value="17"></constructor-arg>
<constructor-arg value="BJT"></constructor-arg>
</bean>
3. 工厂创建(分为实例方法和静态方法实现)
//实例方法创建
<bean id="factory" class="com.cityu.b_createObj.InstanceFactory"></bean>
<bean id="user" factory-bean="factory" factory-method="getInstance"></bean>
//静态方法创建
<bean id="user1" class="com.cityu.b_createObj.InstanceFactory" factory-method="getStaticInstance" lazy-init="true"></bean>