spring总结1/2

(一) Spring概述

1. 是什么

Spring是分层的Java SE/EE 应用full-stack轻量级开源框架,以Ioc(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层Spring MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。
IOC的解耦只能削减计算机的耦合,不能消除,只能降低耦合。

2. 发展历程

1997年IBM提出了EJB的思想
1998年,SUN制定开发标准规范EJB1. 0
1999年,EJB1.1发布
2001年,EJB2. 0发布
2003年,EJR2. 1发布
2006年,EJB3. 0发布
Rod Johnson (spring 之父)
Expert 0ne-to-0ne J2EE Design and Development (2002)
阐述了J2EE使用EJB开发设计的优点及解决方案
Expert 0ne-to-0ne J2EE Development without E JB (2004)
阐述了J2EE开发不使用EJB的解决方式(Spring 雏形)
2017年9月份发布了spring 的最新版本spring 5. 0通用版(GA)

3. 优势

(1)方便解耦,简化开发
通过Spring提供IoC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

(2)AOP编程的支持
通过Spring的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。

(3)声明式事务的支持
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务管理,提高开发效率和质量。

(4)方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。

(5)方便集成各种优秀框架
Spring可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。

(6)降低JavaEE API的使用难度
Spring对JavaEE API(如JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些API的使用难度大为降低。

(7)Java源码是经典的学习范例
Spring的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对Java设计模式灵活运用以及Java技术的高深造诣。它的源代码无意是Java技术最佳实践范例

4. 体系结构

在这里插入图片描述

5. 程序的耦合

(1)耦合和解耦

耦合:程序间的依赖关系;包括:类之间的依赖;方法之间的依赖;
解耦:降低程序间的依赖关系
[实际开发中:应该做到:编译期不依赖,运行时才依赖]

(2)解耦的思路:

第一步:使用反射来创建对象,而避免使用new关键字。
第二步:通过读取配置文件来获取要创建的对象全限定类名

(3)工厂类和配置文件

一个创建Bean(可重用组件)对象的工厂
JavaBean>实体类
它就是创建service和dao对象的。
第一个:需要一个配置文件来配置我们的service和dao
配置的内容:唯一标志=全限定类名(key=value)
第二个:通过读取配置文件中配置的内容,反射创建对象。
配置文件可以是xml也可以是properties

(二)spring的IOC解决程序耦合

spring的IOC不能实现数据库增删改查,也不能实现表现层的请求参数封装,甚至也不能接受请求,但是它可以解耦,降低程序间的依赖关系。

由于我们是使用spring解决依赖关系,并不是真正要做到增删改查的操作,所以此时我们没必要写实体类,并且我们在此处使用的java工程,不是java. Web工程。
官网下载开发包
在这里插入图片描述
【application的Ioc核心容器,根据id获取对象】

//模拟一个表现层,用于调用业务层
public class Client {

	public static void main(String[] args) {
	//1.获取核心容器对象
	ApplicationContext ac = new ClasspathXmlApplicationContext(configLocation:"bean.xml");
	//ApplicationContext ac = new FileSystemXmlApplicationContext("C:\\Users\\zhy\\Desktop\\bean.xml");
   //2.很据i获取Bean对象
	IAccountService as = (IAccountService)ac.getBean( "accountService");
	IAccountDao adao = ac.getBean(name:"accountDao",IAccountDao.class);
	System.out.print(as);
	System.out.print(adao);
	as.saveAccount();
	}

1.ApplicationContext的三个常用实现类:

	ClassPathXmlApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下,不在的话,加载不了。(更常用)
	FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
	AnnotationConfigApplicationContext:它是用于读取注解创建容器的

2.核心容器的两个接口引发的问题

(1)ApplicationContext:(单例对象适用)(实际开发中,采用此接口更常用)
它在构建核心容器时,创建对象采取的策略是采用立即加载的方式,也就是说,只要一读取完配置文件马上就创建配置文件中的配置的对象。

(2)BeanFactory:(多例对象适用)
它在创建核心容器时,创建对象采取的策略是采用延迟加载的方式,什么时候根据id获取对象了,什么时候才能真正的创建对象。

把对象的创建交给spring来管理

3.spring对bean的管理细节

(1)创建bean的三种方式

第一种方式:使用默认构造函数创建

在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。

<bean id="accountService" class="com.dynamic.service.impl.AccountServiceImpl"></bean>
id:取值; class:反射

第二种方式:使用普通工厂的方法创建对象(使用某个类中的方法创建对象,并存入spring容器中 )

<bean id="instanceFactory" class="com.dynamic.factory.InstanceFactory"></bean>
<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>

第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)

<bean id="accountService" class="com.dynamic.factory.StaticFactory" factory-method="getAccountService"></bean>

(2)bean对象的作用范围

bean标签的scope属性:
作用:用于指定bean的作用范围
取值:(常用的单例和多例的)

singleton:单例(默认值)
prototype:多例的
request:作用于web应用的请求范围
session:作用域web应用的会话范围

global-session:作用域集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session
如下图:
在这里插入图片描述

(3)Bean对象的声明周期

单例对象
出生:当容器创建时对象出生
活着:只要容器在,对象一直活着
死亡:容器销毁,对象消亡
【总结:单例对象的声明周期和容器相同】

多例对象
出生:当我们使用对象时spring框架为我们创建
活着:对象只要是在使用过程中就一直活着
死亡:当对象长时间不用,且没有别的对象引用时,由java的垃圾回收机制回收

4.Spring中的依赖注入

依赖注入:DI(Dependency Injection)

(1)是什么

IOC的可以,降低程序间的耦合(依赖关系),依赖关系,以后都交给spring来维护。在当前类需要用到其他类的对象,由spring来为我们提供,我们只需要在配置文件中说明依赖关系的维护:就称之为依赖注入(DI)。

(2)依赖注入:能注入的数据有三类

基本类型和string、其他bean类型(在配置文件中或者注解配置过的bean)、复杂类型/集合类型

(3)注入的方式:有三种

①第一种:使用构造函数提供

使用的标签:constructor-arg
标签内出现的位置:bean标签的内部
标签中的属性:
	Type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某些参数的类型
	Index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
Name:用于指定给构造函数中指定名称的参数赋值
【以上三个用于给指定构造函数中那个参数赋值】

Value:用于提供基本类型和string类型的数据
Ref:用于指定其他的bean类型数据,它指的就是在spring的Ioc核心容器中出现过的bean对象
【以上两种比较常用】

优势:在获取bean对象时,注入数据是必须的操作,否则对象无法创建。
弊端:改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
 示例:

AccountServiceImpl.java写入如下代码:

//账户的业务层实现类
public class AccountServiceImpl implements IAccountService {
//如果是经常变化的数据,并不适用于注入的方式
private String name;
private Integer age;
private Date birthday ;

public AccountServiceImpl(String nane ,Integer age , Date bi rthday){
this .hame = name ;
this.age = age ;
this.birthday = birthday;
}
public void saveAccount(){

System.out.print in(”service中的savelccount方法执行了... "nane+","age+","+birthday) ;
	}
}

test类中写入如下信息:

<bean id="accountService"class="com.dynamic.service.imp1.Ac
countserviceImpl">
<constructor-arg name="name" value="test"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" value="now"></constructor-arg>
</bean>
<!-- 配置一个日期对象-->
<bean id="now" class="java.util.Date"></bean>

模拟一个表现层用户调用业务层:

public class Client {

	public static void main(String[] args) {
	//1.获取核心容器对象
	ApplicationContext ac = new ClasspathXmlApplicationContext(configLocation:"bean.xml");
   //2.很据i获取Bean对象
	IAccountService as = (IAccountService)ac.getBean( "accountService");
	as.saveAccount();
	}

② 第二种:使用set方法提供(更常用)

涉及的标签:property
出现的位置:bean标签的内部
标签的属性:
	Name:用于指定注入时所调用的Set方法名称
	Value:用于提供基本类型和string类型的数据
Ref:用于指定其他的bean类型数据,它指的就是在spring的Ioc核心容器中出现过的bean对象

优势:创建对象时没有明确的限制,可以直接使用默认构造函数。
弊端:如果某个成员必须有值,则获取对象是有可能set方法没有执行。

AccountServiceImpl.java写入如下代码:

//账户的业务层实现类
public class AccountServiceImpl2
inplements IAccountService {

//如果是经常变化的数据,并不适用于往入的方式
private String name;
private Integer age;
private Date birthday;

public void setName(String name) {
this.name = name;
}
public woid setAge(Integer age) {
this.age = age;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public void setAccount() {System.out printIn("service
中的saveccount方法执行了..."+name+","age+","+birthday); 

测试类中写入如下文件:

<bean id="accountService2"class="com.dynamic.service.imp1.Ac
countserviceImpl2">
<property name="name" value="test"></property>
<property name="age" value="18"></property>
<property name="birthday" value="now"></property>
</bean>
<!-- 配置一个日期对象-->
<bean id="now" class="java.util.Date"></bean>

模拟一个表现层用户调用业务层:

public class Client {

	public static void main(String[] args) {
	//1.获取核心容器对象
	ApplicationContext ac = new ClasspathXmlApplicationContext(configLocation:"bean.xml");
   //2.很据i获取Bean对象
	IAccountService as = (IAccountService)ac.getBean( "accountService2");
	as.saveAccount();
	}

③ 第三种:使用注解提供

复杂类型/集合类型的注入
用于给List结构集合注入的标签:
List array set
用于给map结构集合注入的标签:
Map props
结构相同,标签可以互换。
//账户的业务层实现类

public class AccountServiceImp3 implements IAccount Service {
	private string[] myStrs;
	private List<String> mylist;
	private Set<String> mySet ;
	private Map<String,String> myMap; 
	private Properties myProp;
      
	public void setMyList(List<String> myList) {
		this.myList = myList;
	}
	public void setMySet (Set<string> mySet) { 
		this.mySet = mySet ; 
	}
	public void setMyMap(Map<String, String myMap) {
		this myMap = myMap;
	}
	public void setMyProps (Properties myProps) {
		this .myProps = myProps;
	public void saveAccount(){
		System.out.println(Arrays toString(myStrs));
		System.out.println(myList);
		System.out.println(mySet);
		System.out.println(myMap);
		System.out.println(myProps);
	}
}

模拟一个表现层用户调用业务层:

public class Client {

	public static void main(String[] args) {
	//1.获取核心容器对象
	ApplicationContext ac = new ClasspathXmlApplicationContext(configLocation:"bean.xml");
   //2.很据i获取Bean对象
	IAccountService as = (IAccountService)ac.getBean( "accountService3");
	as.saveAccount();
	}

【思考】
Spring的IOC到底能解决什么问题?如何搭建出来Spring基于XML和IOC的开发环境?如何实现类之间的依赖,使用Sping注入?

5.基于注解的IOC配置

学习基于注解的IOC配置,首先要知道,注解配置和xml配置要实现的功能都是一样的,都是要降低程序间的耦合,只是配置的形式不一样。

(1)基于xml的配置

//导入jar包
<packaging>jar</packaging>
//导spring框架
<dependencies>
	<dependency> 
	<groupId>org springframework</groupId>
	<artifactld>spring-context</artifactId>
	sversion>5.0.2. RELEASE</vers ion2
	</dependency>
</dependencies>

在resource下新建一个bean.xml

<!—导入约束-->
<?xmlversion="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">
	<!—把对象的创建交给Spring来管理-->
<bean id="accountService"class="com.dynamic.service.impl.AccountServiceImpl">
</bean>
<bean id="accountDao"class="com.dynamic.dao.imp.AccountDaoImpl"></bean>
</beans>

表现层Client:

(2)基于注解的配置

//账户的业务层实现类
//曾经XML的配置:
<bean id "accountService" class= "com. dynamic.service. impl .AccountServiceImpl”
	scope= "” init method= "”des troy-method= "">
	<property name="" value=""  ref=""></property>
</bean>

①用于创建对象的

他们的作用就和在XmL配置文件中编写一个<bean>标签实现的功能是一样的
	Component :
     作用:用于把当前类对象存入spring容器中
     属性:value用于指定bean的id.当我们不写时,它的默认值是当前	类名,且首宇母改小写。
	Controller:一般用在表现层
	Service: 一般用在务层
	Repository:一般用在持久层
	以上三个注解他们的作用和属性与Component是一模样。
	他们三个是spring框架为我们提共明确的三层使用的注解,使我们的三层对象更加清晰

②用于注入数据的

他们的作用就和在xml配置文件的bean标签中写一个<property>签的作用是样的 

Astowired:
	作用:自动按照类型注。只要容器中有哇一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
	如果ioc容器中没有任何bean的类型和要注人的变量类型配,则报错。
	如果Ioc容器中有多个类型的匹配时,
	出现位置可以是变量上,也可以是方法上
	细节:在使用注解注人时,set方法就不是必须的了.

Qualifier:
	作用:在按照类中注入的基础之上再按照名称注入。它在给类成员注入时不能单使用。但是在给方法参数注人时可以
	属性:value用于指定注bean的id

Resource
	作用:直接按照bean的id注入。它可以独立使用
	属性:name用于指定bean的id。
	
【以上三个】注入都只能注人其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。
另外,集合类型的注入只能通过XML来实现。

Value
	作用:用于注入基本类型和String类型的数据
	属性:
	value用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式)
SpEL的写法,${表达式}

用于改变作用范围的
	他们的的作用就和在bean标签中使用scope的作用是一样的
Scope
	作用:用于指定bean的作用范围
	属性:value:指定范围的取值。常用取值:singleton,prototype

和生命周期相关
	他们的的作用就和在bean标签中使用init-mehod和destory-methode的作用是一样的
	PreDestroy
	作用:用于指定销毁方法
	PostConstruct
	作用:用于指定初始化方法

是谁的el,就去谁规定的位置取值,看{}符号写的位置。如果{}写在jsp文件中,就是jsp的el表达式,一定会去spel获取数据,如果写在spring的配置文件或者注解中,就是Spring的el表达式,会去spring指定的位置取值,如果是写在mybaits的配置文件中,就去mybatis对应的位置取值
在这里插入图片描述
(3)其他配置;

如果把一个子类看成父类型,就只能调用父类型的方法,就close不来。
这时候需要把它看出自己,然后释放,就可以销毁了。

6. 基于XML的IOC,编写Spring的Ioc配置

[基于XML、注解的配置] 在这里插入图片描述

7. spring的新注解

三种配置:Xml(类是别人写好的,存在于jar包中)、注解(类是自己写的)、Xml和注解结合(根据情况选择)
【配置方式的汇总】在这里插入图片描述
(三)spring中的AOP
未完待续…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值