Spring框架

1.Spring简介

Spring优点

1.非侵入式

2.容器

在应用加载时,创建一个 Map,用于存放三层对象。 我们把这个 map 称之为容器。

3.Ioc:控制反转

即将对象创建的权利交给了框架,包括依赖注入和依赖查找

原来: 我们在获取对象时,都是采用 new 的方式。是主动的。

现在: 我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。

作用:削减计算机程序的耦合(解除我们代码中的依赖关系)

4.依赖注入

5.AOP:面向方面的编程

面向方面编程,将日志、安全、事务管理等理解成一共方面,以前这些服务通常是直接写在业务逻辑中,这两个缺点:1,业务逻辑不干净 2,这些服务被很多业务逻辑反复使用,不能复用。AOP解决了这些,将这些服务剥离了出来。

Spring体系结构

在这里插入图片描述

2.Spring Bean的装配模式

2.1 Spring IOC容器

Spring IOC容器的设计主要基于BeanFactory和ApplicationContext这两个接口

BeanFactory是底层接口,ApplicationContext是其子接口,提供更好的功能

2.1.1ApplicationContext的常用实现类

ClassPathXmlApplicationContext

从类路径classPath中寻找指定的XML配置文件,找到并装载ApplicationContext的实例化工作

ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");

FileSystemXmlApplicationContext

采用绝对路径的方式不推荐使用

AnnotationConfigApplicationContext

当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。

2.1.2 ApplicationContext容器由Web服务器实例化

这些放在web.xml文件中

基于ContextLoaderListener实现

指定Spring配置文件的位置
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-name>classpath:applicationContext.xml</param-name>
</context-param>
指定以ContextLoaderListener方式启动Spring容器
<listener>
   <listener-class>
       org.springframework.web.context.ContextLoaderListener
   </listener-class>
</listener>

基于ContextLoaderServlet实现

指定Spring配置文件的位置
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-name>classpath:applicationContext.xml</param-name>
</context-param>
指定以ContextLoaderListener方式启动Spring容器
<listener>
    <servlet-name>context</servlet-name>
   <listener-class>
       org.springframework.web.context.ContextLoaderListener
   </listener-class>
    <load-on-startup>1</load-on-startup>
</listener>

在Spring、Mybatis和SpringMVC的整合开发时,常用这种方式。

2.2 Bean的配置

2.2.1Bean标签简介

作用:
	用于配置对象让 spring 来创建的。
	默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。
属性:
	id:给对象在容器中提供一个唯一标识。用于获取对象。
	class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
	scope:指定对象的作用范围。
		* singleton :默认值,单例的.
		* prototype :多例的.
		* request :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
		* session :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
		* global session :WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么
			globalSession 相当于 session.
	init-method:指定类中的初始化方法名称。
	destroy-method:指定类中销毁方法名称。

2.2.2 Bean的作用范围与生命周期

单例对象:scope="singleton"
	一个应用只有一个对象的实例。它的作用范围就是整个引用。
	生命周期:
		对象出生:当应用加载,创建容器时,对象就被创建了。
		对象活着:只要容器在,对象一直活着。
	对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
多例对象:scope="prototype"
	每次访问对象时,都会重新创建对象实例。
	生命周期:
		对象出生:当使用对象时,创建新的对象实例。
		对象活着:只要对象在使用中,就一直活着。
		对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。

2.2.3 Bean实例化的三种方式

使用无参构造函数

<!--在默认情况下:
它会根据默认无参构造函数来创建类对象。如果 bean 中没有默认无参构造函数,将会创建失败。
-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"/>

spring 管理静态工厂-使用静态工厂的方法创建对象

/**
* 模拟一个静态工厂,创建业务层实现类
*/
public class StaticFactory {
public static IAccountService createAccountService(){
return new AccountServiceImpl();
}
}
<!-- 此种方式是:
使用 StaticFactory 类中的静态方法 createAccountService 创建对象,并存入 spring 容器
id 属性:指定 bean 的 id,用于从容器中获取
class 属性:指定静态工厂的全限定类名
factory-method 属性:指定生产对象的静态方法
-->
<bean id="accountService"
 class="com.itheima.factory.StaticFactory"
 factory-method="createAccountService"></bean

spring 管理实例工厂-使用实例工厂的方法创建对象

第三种方式:spring 管理实例工厂-使用实例工厂的方法创建对象
/**
* 模拟一个实例工厂,创建业务层实现类
* 此工厂创建对象,必须现有工厂实例对象,再调用方法
*/
public class InstanceFactory {
public IAccountService createAccountService(){
return new AccountServiceImpl();
}
}
<!-- 此种方式是:
先把工厂的创建交给 spring 来管理。
然后在使用工厂的 bean 来调用里面的方法
factory-bean 属性:用于指定实例工厂 bean 的 id。
factory-method 属性:用于指定实例工厂中创建对象的方法。
-->
<bean id="instancFactory" class="com.itheima.factory.InstanceFactory"></bean>
<bean id="accountService"
 factory-bean="instancFactory"
      factory-method="createAccountService"></bean>

3.Spring 依赖注入

依赖注入:Dependency Injection。它是 spring 框架核心 ioc 的具体实现。 我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。 ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。 那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了。 简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

3.1构造函数注入

java代码部分

public class AccountServiceImpl implements IAccountService {
	private String name;
	private Integer age;
	private Date birthday;
	public AccountServiceImpl(String name, Integer age, Date birthday) {
		this.name = name;
		this.age = age;
		this.birthday = birthday;
	}
	@Override
	public void saveAccount() {
		System.out.println(name+","+age+","+birthday);
	}
}

xml部分

<!-- 使用构造函数的方式,给 service 中的属性传值
	要求:
	类中需要提供一个对应参数列表的构造函数。
	涉及的标签:
	constructor-arg
	属性:
		index:指定参数在构造函数参数列表的索引位置
		type:指定参数在构造函数中的数据类型
=======上面三个都是找给谁赋值,下面两个指的是赋什么值的==============
		value:它能赋的值是基本数据类型和 String 类型
		ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean
-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
	<constructor-arg name="name" value="张三"></constructor-arg>
	<constructor-arg name="age" value="18"></constructor-arg>
	<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<bean id="now" class="java.util.Date"></bean>

3.2 Set方法注入

java代码部分

public class AccountServiceImpl implements IAccountService {
	private String name;
	private Integer age;
	private Date birthday;
	public void setName(String name) {
		this.name = name;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	@Override
	public void saveAccount() {
		System.out.println(name+","+age+","+birthday);
	}
}

xml配置

<!-- 通过配置文件给 bean 中的属性传值:使用 set 方法的方式
涉及的标签:
	property
属性:
	name:找的是类中 set 方法后面的部分
	ref:给属性赋值是其他 bean 类型的
	value:给属性赋值是基本数据类型和 string 类型的
实际开发中,此种方式用的较多。
-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
	<property name="name" value="test"></property>
	<property name="age" value="21"></property>
	<property name="birthday" ref="now"></property>
</bean>
<bean id="now" class="java.util.Date"></bean>

3.3对集合属性的注入

java代码部分

public class AccountServiceImpl implements IAccountService {
	private String[] myStrs;
	private List<String> myList;
	private Set<String> mySet;
	private Map<String,String> myMap;
	private Properties myProps;
	public void setMyStrs(String[] myStrs) {
		this.myStrs = myStrs;
	}
	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;
	}
	@Override
	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);
	}
}

xml配置

<!-- 注入集合数据
	List 结构的:
		array,list,set
	Map 结构的
		map,entry,props,prop
-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<!-- 在注入集合数据时,只要结构相同,标签可以互换 -->
<!-- 给数组注入数据 -->
<property name="myStrs">
<set>
	<value>AAA</value>
	<value>BBB</value>
	<value>CCC</value>
</set>
</property>
<!-- 注入 list 集合数据 -->
<property name="myList">
  <array>
	<value>AAA</value>
	<value>BBB</value>
	<value>CCC</value>
  </array>
</property>
<!-- 注入 set 集合数据 -->
<property name="mySet">
 <list>
	<value>AAA</value>
	<value>BBB</value>
	<value>CCC</value>
 </list>
</property>
<!-- 注入 Map 数据 -->
<property name="myMap">
 <props>
	<prop key="testA">aaa</prop>
	<prop key="testB">bbb</prop>
 </props>
</property>
<!-- 注入 properties 数据 -->
<property name="myProps">
 <map>
	<entry key="testA" value="aaa"></entry>
	<entry key="testB">
		<value>bbb</value>
	</entry>
 </map>
</property>
</bean>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值