spring框架(二)——spring概述与spring的核心之IOC
来源:互联网 发布:高校邦网络课程登录 编辑:程序博客网 时间:2024/06/05 19:47
上面一节我们说了spring的体系和jar包的依赖关系,这节笔者主要详解一下spring3.x
一、Spring概述
1、Spring是什么?
Spring是分层的Java SE/EE应用 full-stack轻量级开源框架,以IoC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层Spring MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。2、Spring3.X的体系结构
4、Spring带来的好处
方便解耦,简化开发通过Spring提供的IoC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
AOP编程的支持
通过Spring的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
声明式事务的支持
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。
方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。
方便集成各种优秀框架
Spring可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。
降低JavaEE API的使用难度
Spring对JavaEE API(如JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些API的使用难度大为降低。
Java源码是经典学习范例
Spring的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。它的源代码无意是Java技术的最佳实践的范例。
5、Spring的资源
5.1 下载开发资源包
官方网站: http://spring.io/5.2、Spring的资源包介绍
spring Framework的官方发行包内部结构为:
5.3、关于资源包的说明
Spring Framework官方最新版本是4.3.2。但是能下载到的就是3.2,这是Spring3这个版本的最后一个官方资源包。之后的版本全用MAVEN整合了。Spring依赖的第三方资源包能下载的版本就是3.0.2。后面的也都整合到MAVEN里面去了。
6、搭建Spring核心开发环境
6.1、拷贝最基本的核心jar包
根据第一节。添加这4个jar包以及它的依赖包(spring-Context其实还依赖了aop但是这里因为讲解IOC所以不用依赖也是可以的)。所以上图为他们的4个jar包名称。
6.2、核心依赖的jar包(日志输出)
commons-logging或log4j:用哪个都行。6.3、Spring的配置文件:基于xml或注解的方式
(下面搭建项目时在讲解)
概述部分讲解完毕。下面开始spring的核心之一IOC部分
二、Spring的核心之IoC(Inversion of Control 控制反转)
1、IoC是什么?
注意:这里需要理解什么是注入。(举例,比如普通的set方法就是一种注入等等。)
2、Spring容器
Spring容器简单理解就是用于存放对象的一个boss那么一个东西。3、Spring的IoC入门(注意:这里只是IOC的入门案例,了解ioc是怎么个过程)
3.1、建立一个java工程(没有整合web项目,所以jar工程就够用了)
3.2、导入Spring的核心jar包(5个jar包)
3.3、建立一个XML配置文件
注意:现在xml文件用什么名字无所谓。
3.4、资源交给Spring容器管理(当你写好了controller层,service层,以及dao层时需要交给spring来管理他们的关系)
比如:写好了dao层之后:
3.5、Spring容器的初始化及资源的获取
配置依赖注入:service与dao层之间的关系:
在service层中写一个register方法,调用dao层的方法(注入的dao中有save方法)如下:
package springIoc.service;import springIoc.dao.XXDao1;public class XXService1 {private XXDao1 xxDao1;public void setXxDao1(XXDao1 xxDao1) {this.xxDao1 = xxDao1;}public void rgeister(){xxDao1.save();}}初始化和资源的获取测试:
package springIoc.test;import org.springframework.context.support.ClassPathXmlApplicationContext;import springIoc.service.XXService1;public class Client {public static void main(String[] args) {/* 注意这是直接new对象获取,耦合度很高,没有调用spring来管理的bean == 不采用 * XXService1 xxService1 = new XXService1();xxService1.rgeister();*///Spring容器的初始化ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("springIoc/bean.xml");//获取资源//XXDao1 xxdao1 = (XXDao1) ac.getBean("xxDao1");//xxdao1.save();XXService1 xxService1 = (XXService1) ac.getBean("xxService1");xxService1.rgeister();}}结果成功!
4、Spring中API的体系结构(了解)
4.1、核心接口和类
BeanFactory:它使用的是延迟加载思想。当我们需要用bean时,才去创建对象。ApplicationContext:它继承自BeanFactory接口,还继承了很多其他接口。功能比BeanFactory强大。它用的不是延迟加载思想,而是在加载配置文件时就创建了。(推荐)
FileSystemXmlApplicationContext:配置文件在本地磁盘上,使用该类加载。
ClassPathXmlApplicationContext :配置文件在classpath中,使用此类加载。
特别注意:以上主要ioc已经讲解完毕!下面的Ioc配置部分很重要,两种方式在实际开发中用到的都很多!
5、基于XML的spring的IoC配置
5.1、Spring实例化bean的方式
a、调用默认的构造方法 (推荐)
<!-- dao层 --><bean id="xxDao1" class="springIoc.dao.XXDao1"></bean><bean id="xxDao2" class="springIoc.dao.XXDao2"></bean>b、静态工厂方法初始化:老系统才有可能用到(现在已经完全不用了)
c、实例工厂方法初始化:老系统才有可能用到(现在已经完全不用了)
5.2、Bean的作用范围(Bean下的scope标签)
* scope属性的取值:* singleton:默认值.单例的.Spring生成Bean的时候采用的是单例的模式.* prototype:多例的.Spring生成Bean的时候采用的是多例的模式.每次getBean的时候都会得到一个新的Bean的实例.(与Struts2整合时要使用此值)* request:应用在web应用中.创建一个Bean的实例将Bean实例存入到request域中.* session:应用在web应用中.创建一个Bean的实例将Bean的实例存入session域中.* globalsession:应用在web应用中.全局session.一般用于Porlet应用环境.如果没有Porlet环境.配置全局session等价于session.
5.3、Bean的生命周期方法
init-method:Bean初始化的时候执行的方法.
destroy-method:
Bean销毁的时候执行的方法.必须是在scope=”singleton”情况下使用.
<bean id="xxDao1" class="springIoc.dao.XXDao1" init-method="init" destroy-method="destory"></bean>拓展:
Bean的完整的生命周期:
Spring框架管理Bean的时候,非常精确.Bean的生成过程中有11个步骤.11个步骤才构成了Bean的完整的生命周期.1.instantiate bean对象实例化2.populate properties 封装属性3.如果Bean实现BeanNameAware 执行 setBeanName4.如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext5.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization6.如果Bean实现InitializingBean 执行 afterPropertiesSet 7.调用<bean init-method="init"> 指定初始化方法 init8.如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization9.执行业务处理10.如果Bean实现 DisposableBean 执行 destroy11.调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy* 第三步和第四部为了让Bean了解Spring的环境的..* 第五步和第八部是实现了一个接口BeanPostProcessor.注意:当非单例时,初始化方法正常执行,但是销毁方法就不会执行了。
5.4、依赖注入(DI)
a、构造器注入(调用默认构造方法):通过传参数
0 先定义一个bean类,只提供有参的构造方法(并给每个参数提供get方法,方便测试时判断是否注入进去值)
package springIoc.bean;import java.util.Date;public class Bean1 {private String name;private int age;private Date birthday;//提供了有参构造方法,没有提供默认的构造方法public Bean1(String name, int age, Date birthday) {super();this.name = name;this.age = age;this.birthday = birthday;}public String getName() {return name;}public int getAge() {return age;}public Date getBirthday() {return birthday;}}1、编写bean.xml交给spring管理这个类。
2.编写测试类,判断是否注入成功
package springIoc.test;import org.springframework.context.support.ClassPathXmlApplicationContext;import springIoc.bean.Bean1;public class Client {public static void main(String[] args) {//Spring容器的初始化ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("springIoc/bean.xml");//获取资源Bean1 bean1 = (Bean1) ac.getBean("bean1");System.out.println("姓名:"+bean1.getName()+"年龄:"+bean1.getAge()+"现在时间:"+bean1.getBirthday());}}打印出:姓名:小马同志年龄:26现在时间:Fri Oct 27 09:47:20 CST 2017
b、属性注入:推荐(也是常用的)
0 先定义一个bean类,定义的字段需要提供setter方法(不然注入不进去)并提供默认的构造方法(必须)
package springIoc.bean;import java.util.Date;public class Bean1 {private String name;private int age;private Date birthday;public Bean1() {super();}public String getName() {return name;}public int getAge() {return age;}public Date getBirthday() {return birthday;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}public void setBirthday(Date birthday) {this.birthday = birthday;}}1、编写bean.xml交给spring管理这个类。
<bean id="now" class="java.util.Date"></bean> <bean name="bean1" class="springIoc.bean.Bean1"><!-- 属性注入 --><property name="name" value="小马"></property><property name="age" value="26"></property><property name="birthday" ref="now"></property></bean>2.编写测试类
package springIoc.test;import org.springframework.context.support.ClassPathXmlApplicationContext;import springIoc.bean.Bean1;public class Client {public static void main(String[] args) {//Spring容器的初始化ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("springIoc/bean.xml");//获取资源Bean1 bean1 = (Bean1) ac.getBean("bean1");System.out.println("姓名:"+bean1.getName()+"年龄:"+bean1.getAge()+"现在时间:"+bean1.getBirthday());}}测试成功。
c、p名称空间(不做细讲)
d、SpEL(Spring Expression Lanaguage)
e、注入集合数据
5.5、团队开发:多个Spring配置文件
两种形式:* 加载配置文件的时候一并引入.* ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml", "applicationContext2.xml");* 总的配置文件中引入其他的配置文件.* <import resource="applicationContext2.xml"/>基于xml的配置文件就讲解到这。需要会。下面说一下基于注解的配置也是同样重要,
6、基于注解的spring的IoC配置
6.1、注解的使用前提(3个步骤必须有的!)
a、引入context的名称空间b、指定要扫描的包
c、在Bean上面加入@Component注解
0、配置a和b的步骤
1 之后执行c在指定的类中添加注解(control层和service层以及dao层都需要添加各自的注解)(稍后会有详细的注解介绍)
package springIoc.dao;import org.springframework.stereotype.Component;/** * @Component是spring的一个注解,它是把XXDao1看做一个组件。 * 就相当于xml中 <bean id="xxDao1" class="springIoc.dao.XXDao1"></bean> * @author mch * */@Componentpublic class XXDao1 {public void save() {System.out.println("SPRING3.XIOC成功了");}}注意:@Component(value="xxDao1") 也可以写成这种注解而value值相当于bean的id
2、编写测试类运行结果
package springIoc.test;import org.springframework.context.support.ClassPathXmlApplicationContext;import springIoc.dao.XXDao1;public class Client {public static void main(String[] args) {//Spring容器的初始化ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("springIoc/springxml.xml");//获取资源XXDao1 xxDao1 = (XXDao1) ac.getBean("xxDao1");xxDao1.save();}}
6.2、常用注解
a、@Component作用:让Spring容器管理当前的Bean(实例化)
属性:
value:指定bean的名称。默认值是当前类简单名称(不是全类名)首字母小写。
b、@Component的衍生注解@Controller @Service @Repository
作用:和@Component作用一样,让Spring容器管理(实例化)当前的bean。
属性: value:指定bean的名称。默认值是当前类的简单类名首字母小写
特点:在三成架构中,每个注解对应一层,使语义更加明确。
@Controller:一般用在表现层,比如struts2的action上
@Service:一般用在业务层,比如Service实现
@Repository:一般用在持久层,比如Dao实现
c、@Autowired
作用:自动按类型注入需要的对象。当使用了该注解时,setter就不是必须的了。
属性:
required:是否必须注入成功。默认值是true。
true:必须注入成功,如果出现注入失败,抛出异常。
false:不一定注入成功,不抛异常。
注意事项:
一个Service接口:IBookService
两个Service实现:BookServiceImpl1 BookServiceImpl2
由于@Autowired是自动按类型注入,当使用接口类型时,就看变量的名称,如果变量名称是bookServiceImpl1,则使用BookServiceImp1这个实现类,
如果变量名是bookServiceImpl2,则使用BookServiceImpl2这个实现类。如果没有符合规范的名称(类名首字母小写),则报错。
到底注入哪个实现类:
@Autowried
private BookService bookServiceImpl1;//注入BookServiceImpl1
@Autowried
private BookService bookServiceImpl2;//注入BookServiceImpl2
@Autowried
private BookService bookService;//注入失败
d、@Value
作用:注入基本类型和String。
属性:value:SpEL表达式,要注入的值
package springIoc.dao;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;/** * @Component是spring的一个注解,它是把XXDao1看做一个组件。 * 就相当于xml中 <bean id="xxDao1" class="springIoc.dao.XXDao1"></bean> * @author mch * */@Component(value="xxDao1")public class XXDao1 {@Value("小码")private String name;public void save() {System.out.println("SPRING3.XIOC成功了");}public String getName() {return name;}}提供get方法查看是否注入成功
package springIoc.test;import org.springframework.context.support.ClassPathXmlApplicationContext;import springIoc.dao.XXDao1;public class Client {public static void main(String[] args) {//Spring容器的初始化ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("springIoc/springxml.xml");//获取资源XXDao1 xxDao1 = (XXDao1) ac.getBean("xxDao1");xxDao1.save();System.out.println(xxDao1.getName());}}结果为成功
e、@Qualifier
作用:要配合@Autowried来一起使用,通过它指定要注入的bean的名称。按类型注入失效了。
属性:value:要注入的bean的名称
f、@Resource
作用:如同@Autowire和@Qualifier,是规范JSR-250中定义的(JCP)。通过指定bean的名称注入对象。
属性: name:要注入的bean的名称
g、@PostConstruct(了解)
作用:用在初始化方法上。生命周期有关
h、@PreDestroy(了解)
作用:用在销毁方法上。生命周期有关
i、@Configuration和@Bean(了解)
作用:@Configuration指定当前类为配置类,用于加载@Bean的定义。@Bean用于定义bean的名称,用法是@Bean(name="beanName")
注意:该类要被设置在注解自动扫描对应的包下。
6.3、Spring中使用单元测试
a、导入jar包:
spring-test-3.2.0.RELEASE.jar
b、设置Junit运行器和Spring配置文件
步骤:
0、编写一个类(dao层)
package springIoc.dao;import org.springframework.stereotype.Component;/** * @Component是spring的一个注解,它是把XXDao1看做一个组件。 * 就相当于xml中 <bean id="xxDao1" class="springIoc.dao.XXDao1"></bean> * @author mch * */@Component(value="xxDao1")public class XXDao1 {public void save() {System.out.println("SPRING3.XIOC成功了");}}1、设置是spring配置文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" 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-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd "> <!-- 指定Spring要扫描的包 注意:它会扫描当前包和当前包的子包下的所有类(base-package:以点分割包名) --><context:component-scan base-package="springIoc"></context:component-scan></beans>2、进行编写测试类。进行测试
package springIoc.dao;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)//指定新的运行器,该运行前会初始化Spring容器,并注入资源,执行Junit单元测试@ContextConfiguration(locations={"classpath:springIoc/springxml.xml"})//指定spring容器要加载的配置文件public class XXDao1Test {@Autowiredprivate XXDao1 xxDao1;@Testpublic void test1(){xxDao1.save();}}结果成功!
总结:
其实spring的Ioc原理是 IOC原理:工厂 + 反射 + 配置文件.
那么Spring的Ioc就说到这,后面在继续了解它。
- spring框架(二)——spring概述与spring的核心之IOC
- spring框架学习笔记(二)——spring的ioc之Resource
- Spring的核心之IOC
- Spring入门之Spring核心与概述
- Spring 核心之IOC
- Spring核心之IoC
- Spring核心之IoC
- Spring 框架概述(三)之IoC 容器
- Spring框架IOC(控制反转)的核心
- Spring—IoC(二)
- (二)Spring的IOC&DI概述
- Spring核心(二)IoC介绍
- Spring核心(二)IoC介绍
- (六)Spring核心框架 - IOC的源码解析
- Spring框架之IoC容器—概览
- Spring框架之IOC
- spring框架之ioC
- spring框架之IOC
- chmod、chown、umask、隐藏权限lsattr/chattr
- iOS返回根视图、特定视图的方法
- 获取android签名证书的sha1值
- 如何添加自己的应用到openwrt上
- 用户列表完整版
- spring框架(二)——spring概述与spring的核心之IOC
- Java main函数中的String[] args
- ZIP压缩算法详细分析及解压实例解释
- 分布式定时任务
- 数浪最难是起点
- java多线程
- 构造函数与析构函数
- RabbitMq3.6.12 (centos7)安装与基本使用
- 8.PHP 命令行下的世界