什么是Spring?
Spring:是一个开源的JavaSE/EE开发的一站式框架。
一站式框架:有EE开发的每一层解决方案。
- WEB层:SpringMVC
- Service层:Spring的Bean管理,Spring声明式事务
- DAO层:Spring的Jdbc模板,Spring的ORM模块
为什么要用Spring?
- 方便解耦,简化开发:提供IoC容器,可以对象间的依赖关系交给Spring控制,避免硬编码造成的过度耦合;不必再为底层需求编码,从而专注于上层应用。
- 支持AOP编程:面向切面编程。OOP实现不了可用AOP。
- 声明式事务的支持:可以通过声明式的方式灵活地进行事务的管理。
- 方便程序测试:对JUnit4支持。
- 方便集成各种优秀框架。
什么是IoC?
IoC(Inversion of Control):控制反转。将对象的创建权反转给(交给)Spring。
IoC的底层实现原理:工厂+反射+配置文件
具体实现:
1.编写接口 (UserDAO) 及 实现类(UserDAOImpl)
2.编写配置文件
<bean id="userDAO" class="com.google.spring.UserDAOImpl"></bean>
3.编写测试类
@Test
public void demo1(){
//创建Spring的工厂
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("applicationContext.xml");
UserDAO userDAO = (UserDAO)applicationContext.getBean("userDAO");
userDao.save();
}
IoC和DI的区别:
IoC:控制反转,将对象的创建权反转给了Spring。
DI:依赖注入,前提必须有IoC的环境,Spring管理这个类的时候将类的依赖的属性注入(设置)进来。
Spring的工厂类
ApplicationContext 继承 BeanFactory。
- BeanFactory:老版本的工厂类。调用getBean的时候,才会生成类的实例。
- ApplicationContext :新版本的工厂类。加载配置文件的时候,就会将Spring管理的类都实例化。(就是把类的实例化提前了)
ApplicationContext 有两个实现类:
- ClassPathXmlApplicationContext :加载类路径下的配置文件(上面测试类中用过)
-
FileSystemXmlApplicationContext :加载文件系统下的配置文件
Spring工厂类的核心类图:
Spring的Bean管理(XML方式)
什么是bean ?
bean是一个由Spring IoC容器 实例化、组装和管理的对象。
有什么作用?
配置和管理需要实例化的类。
Spring的Bean的实例化方式:
无参构造方法的方式(默认);静态工厂实例化的方式;实例工厂实例化的方式
Bean的生命周期
- 实例化Bean对象(构造方法或工厂方法);
- 设置对象属性(依赖注入);
- 如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID;
- 如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身;
- 若实现了BeanPostProcessor接口,则调用postProcessBeforeInitialization(Object bean, String beanname)方法在初始化之前对Bean进行前置处理;
- 若实现了InitializingBean接口,则调用afterPropertiesSet()方法;
- 若自定义了初始化方法,则调用配置文件init-method属性对应的初始化方法;
- 若实现了BeanPostProcessor接口,则调用postProcessAfterInitialization(Object bean, String beanname)方法在初始化之后对Bean进行后置处理;
- 使用Bean;
- 如果实现了DisposableBean接口,则调用实现的destory()方法;
- 若自定义了销毁方法,则调用配置文件destory-method属性对应的销毁方法;
<!-- Spring的生命周期配置=============================== -->
<!-- init-method -->
<!-- destroy-method -->
<bean id="" class="" init-method="" destroy-method=""></bean>
Bean的作用范围的配置(重点)
- singleton :默认的,Spring会采用单例模式创建这个对象。
- prototype :多例模式。(Struts2和Spring整合一定会用到)
- request :web项目中,每一个HTTP请求都会创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。。
- session :web项目中,每个Session中有一个Bean的实例,在Session过期后,Bean会随之失效。
-
globalsession :应用在web项目中,必须在porlet环境下使用。但是如果没有这种环境,相对于session。
Spring的属性注入方式(xml方式):
-
构造方法的方式
-
Set方法的方式
-
P名称空间的属性注入(Spring2.5以后)
-
SpEL的属性注入(Spring3.0以后)(SpEL:Spring Expression Language,Spring的表达式语言。语法:#{ } )
问题:每次请求都会创建一个Spring的工厂,这样浪费服务器资源,应该一个项目只有一个Spring的工厂。
解决方案:使用Spring核心监听器ContextLoaderListener 。
原理及过程:监听ServletContext对象的创建和销毁。
- 在服务器启动的时候,创建一个Spring的工厂。
- 创建完工厂,将这个工厂类保存到ServletContext中。
- 每次使用的时候都从ServletContext中获取。
Spring的IOC的注解开发
配置组件扫描:
<!-- 为了扫描类上的注解 -->
<context:component-scan base-package="com.google.spring.demo01"></context:component-scan>
在没有扫描的情况下:
使用属性注入的注解:@Resource、@Value、@AutoWired、@Qulifier
<context:annotation-config />
@Component :定义Bean(修饰一个类,将这个类交给Spring管理)。
在Spring 2.5后为@Component 添加了三个衍生的注解(功能类似,都是修饰类的):
@Repository :定义DAO层Bean
@Service :Service层
@Controller :WEB层
如果bean所在的分层明确,就使用上面的三个注解。如果分层不明确,就可以使用@Component。
属性注入(注解方式):
1.设置普通属性的值 :@Value
2.对象属性 :@Resource (注解属于JavaEE,默认按名称完成属性注入,当找不到名称匹配的bean再按类型装配)
- @Autowired :按类型注入属性(默认)(注解属于Spring)
- @Qualifier:按名称 (注解属于Spring)
@Autowired
private UserDao userDao;
@Qualifier("userDao")
private UserDao userDao;
@Resource(name="userDao")
private UserDao userDao;
@Value和@Autowired它们可以修饰属性,也可以修饰setter方法,如果写在属性上,就不需要setter方法。
Bean的其他注解:
@Scope:Bean作用范围的注解。(可设置属性为:singleton :默认单例;prototype :多例;...)
XML方式和注解方式比较:
- XML方式 :适用性更广,结构清晰,维护方便。
- 注解方式 :适用类是自己定义,开发更方便。
XML和注解的整合开发
- 注解:属性注入
- XML:定义类(管理Bean)
Spring整合JUnit4单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo1 {
@Resource(name="userService")
private UserService userService;
@Test
public void demo2(){
userService.save();
}
}
如有错误,欢迎留言指正 * _ *