1.Spring框架介绍:
Spring是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。
Spring可以去整合表现层,业务层,持久层的开源的框架,在表现层提供了与Struts2框架的整合,在业务逻辑层可以管理事务和记录日志,在持久层可以整合Hibernate和JdbcTemplate等技术。
框架的主要优势之一就是分层架构,分层架构允许使用者选择哪一个组件。
Spring的核心就是控制反转(IOC控制反转)和面向切面AOP。
1.1 Spring的优点
1.方便解耦,简化开发,Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理。IOC的作用。
2.AOP编程的支持,Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。(可扩展性)
3.声明式事务的支持,只需要通过配置就可以完成对事务的管理,而无需手动编程。
有两种实现方式:一种是动态代理,一种是静态代理
4.方便程序的测试,Spring对Junit4支持,可以通过注解方便的测试Spring程序。
5.方便集成各种优秀框架,Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持。
6.降低JavaEE API的使用难度,Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。
2. Spring—IOC
2.1 什么是IOC
IOC——Inverse of Control ,控制反转,将对象的创建权力反转给Spring框架!!
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。
Spring工厂读取配置文件
2.2 写一个IOC程序
首先我们创建一个Java maven的项目
在项目src目录下的main目录中的java目录下随便创建一个目录然后在该目录下创建一个service的包,包中写一个接口
public interface UserService {
public void hello();
}
再写一个接口实现类
public class UserServiceImpl implements UserService {
@Override
public void hello() {
System.out.println("IOC!!!");
}
}
然后去test下写一个测试类测试一下
public class test {
@Test
public void run(){
UserService userService= new UserServiceImpl();
userService.hello();
}
}
ok了
如果我们没有IOC(控制反转)就需要向上面一样自己手动new一个对象去实现这个hello方法。
如果我们要实现IOC(控制反转)该怎么做?
首先,编写Spring核心的配置文件,在src目录下创建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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--IOC管理bean-->
<bean id="userService" class="com.qcbyjy.service.UserServiceImpl" />
</beans>
然后引入一个标签,该标签有两个属性一个id 一个class,id就是你给这个对象起的名字,class就是你的这个类的所在的位置。
在spring的配置文件中配置一个bean,就相当于把这个类交给Spring的IOC容器去管理,Spring管理的对象叫做bean对象。
然后在测试类里写一个测试方法
@Test
public void run1(){
//spring的工厂对象 bean工厂
//去读取spring的配置文件
//Spring 的工厂是负责加载并管理所有的
ApplicationContext ac=new ClassPathXmlApplicationContext("application.xml");
//工厂对象的方法
UserService userService= (UserService) ac.getBean("userService");
//调用userService实现的方法
userService.hello();
}
我们来看一下这Application这个接口,这个接口最下面有两个实现类,一个ClassPathXmIApplicaitonContext(加载类路径下的配置文件),一个是FileSystemXmlAppcationContext(就是直接把配置文件的地址写上)
2.3 两种创建方式的对比
自己new对象
@Test
public void run(){
UserService userService= new UserServiceImpl();
UserService userService1= new UserServiceImpl();
System.out.println(userService);
System.out.println(userService1);
}
工厂创建对象的方式
@Test
public void run1(){
//spring的工厂对象 bean工厂
//去读取spring的配置文件
//Spring 的工厂是负责加载并管理所有的
ApplicationContext ac=new ClassPathXmlApplicationContext("application.xml");
//工厂对象的方法
UserService userService= (UserService) ac.getBean("userService");
UserService userService1= (UserService) ac.getBean("userService");
//调用userService实现的方法
System.out.println(userService);
System.out.println(userService1);
}
我们会发现工厂创建的是同一对象,就是说在不做任何改变的情况下,我们使用spring的工厂创建对象的时候,默认的是单例模式。
2.4 Spring框架的Bean管理的配置文件方式
class属性,Bean对象的全路径。
scope属性,scope属性代表Bean的作用范围。
singleton单例(默认值),最常用的方式。
prototype多例
request应用在Web项目中,每次HTTP请求都会创建一个新的Bean
session应用在Web项目中,同一个HTTP Session 共享一个Bean
Bean对象的创建和销毁的两个属性配置
说明:Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法
init-method:当bean被载入到容器的时候调用init-method属性指定的方法
destroy-method:当bean从容器中删除的时候调用destroy-method属性指定的方法
单例对象的销毁:随着容器工厂的销毁而销毁
多例对象的销毁:垃圾回收机制进行回收
所以这个destroy-method的方法我们没法看到,只能看一下init_method的实现。
首先,在UserServiceImpl类下的写一个init的方法。
/**
* 对象被创建前的初始化的方法
*/
public void init(){
System.out.println("init方法的执行");
}
指定初始化的方法,然后我们去测试一下效果
public void run1(){
//spring的工厂对象 bean工厂
//去读取spring的配置文件
//Spring 的工厂是负责加载并管理所有的
ApplicationContext ac=new ClassPathXmlApplicationContext("application.xml");
//工厂对象的方法
UserService userService= (UserService) ac.getBean("userService");
userService.hello();
}
这个初始化方法在单例和多例模式下运行的时机不太一样,也可以说单例和多例模式下创建对象的时机是不一样的。
我们来看一下:
先在创建工厂对象下加一行分隔符
然后在单例模式(默认)下运行看一下,
我们可以看到在单例模式在创建工厂的时候就把对象也给创建了。
多例模式下再运行看一下
就会发现我们多例模式下,是创建完工厂后,当需要创建对象时才会创建对象,进行初始化。
2.5 Spring实例对象的三种方式
默认
无参数的构造方法(基本上都是默认)