spring框架(二)——spring概述与spring的核心之IOC

上面一节我们说了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 执行 setBeanName
4.如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
5.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization
6.如果Bean实现InitializingBean 执行 afterPropertiesSet 
7.调用<bean init-method="init"> 指定初始化方法 init
8.如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization
9.执行业务处理
10.如果Bean实现 DisposableBean 执行 destroy
11.调用<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
 *
 */
@Component
public 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 {

	@Autowired
	private XXDao1 xxDao1;
	
	@Test
	public void test1(){
		xxDao1.save();
	}
}
结果成功!

总结:

其实spring的Ioc原理是 IOC原理:工厂 + 反射 + 配置文件.


那么Spring的Ioc就说到这,后面在继续了解它。

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敬业小码哥

你的鼓励是我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值