一、spring综述
1. 核心
IoC(反转控制)和AOP(面向切面编程)
2. 优势
方便解藕,简化开发
AOP编程的支持
声明式事务的支持
方便程序的测试
降低JavaEEAPI的使用难度
3. 体系结构
4. 程序之间的耦合
概念:程序间的依赖关系
种类:类之间的依赖、方法之间的依赖
解藕:降低程序之间的关系
要求:编译期不依赖,运行时才依赖。
解耦方案:第一步,使用反射创建对象,避免使用new关键字。
通过读取配置文件来获取要创建的对象全限定类名
二、工厂模式解耦
Bean:在计算机英语中,有可重用组件的含义。
JavaBean:用Java语言编写的可重用组件。 JavaBean范围大于实体类
创建Bean对象的工厂:创建我们的service和dao对象
三、 使用spring 的IoC解决程序耦合
1.概念
Ioc(Inversion of Control,控制反转)创建对象的权力交给框架,是框架的重要特征,并非
面向对象编程的专用术语,它包括依赖注入(Dependency Injection,简称DI)和依赖查找
(Dependency Lookup)。
2. 作用
削减计算机程序的耦合(解除我们代码中的依赖关系)
3.开发包
官网http://spring.io
maven工程
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
4. 案例
bean.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">
<!--把对象的创建交给spring来管理-->
<bean id="accountService" class="com.hyg.service.impl.AccountServiceImpl"></bean>
<bean id="accountDao" class="com.hyg.dao.impl.AccountDaoImpl"></bean>
</beans>
测试方法
public static void main(String[] args) {
//1. 获取核心容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
//2. 根据id获取bean对象
AccountService as = (AccountService) ac.getBean("accountService");//得到oject类型,然后强制类型转换
AccountDao adao = ac.getBean("accountDao",AccountDao.class);//传递字节码文件,根据字节码文件转化为想得到的对象
System.out.println(as);
System.out.println(adao);
}
5. 两个核心容器
① ApplicationContext(使用的更多)
在构建核心容器时创建对象的思想时采用立即加载的方式,即读取完配置文件,就立即创建配置文件中配置的对象。适用于单例对象。ApplicationContext是BeanFactory的子接口。
② BeanFactor
在构建核心容器时创建对象的思想时采用延迟加载的方式,即当根据id获取对象的时候才创建对象。适用于多例对象。
6.ApplicationContext的三个常用实现类
- ClassPathXmlApplicationContext:只能加载类路径下的配置文件
- FileSystemXmlApplicationcontext:可以加载磁盘任意路径下的配置文件(必须要访问权限)
- AnnotationConfigApplicationcontext:用于读取注解,创建容器
7. 创建bean的三种方式
①使用默认构造方法创建
在spring的配置文件中使用bean标签,配置id和class属性后,且没有其他属性和标签时,采用的就是默认构造方法创建bean对象,此时如果类中没有默认构造方法,则对象无法创建。
<bean id="accountService" class="com.hyg.service.impl.AccountServiceImpl">
</bean>
② 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring对象)
类可能存在于jar包中,无法修改源码来提供默认构造方法时使用。
public class InstanceFactory {
public AccountService getAccountService (){
return new AccountServiceImpl();
}
}
<bean id="InstanceFactory" class="com.hyg.factory.InstanceFactory"></bean>
<bean id="accountService" factory-bean="InstanceFactory" factory-method="getAccountService"></bean>
③ 使用静态工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)
public class StaticFactory {
public static AccountService getAccountService (){
return new AccountServiceImpl();
}
}
<bean id="accountService" class="com.hyg.factory.StaticFactory" factory-method="getAccountService"></bean>
8. bean的作用范围 :scope
bean标签的scope属性:用于指定bean的作用范围。
取值:
- singleton:单例的(默认值)
- prototype:多例的
- request:作用于web应用的请求范围
- session:作用于web应用的会话范围
- global-session:作用于集群环境的会话范围,当不是集群环境时,等效于session
9. bean对象的生命周期
① 单例对象
创建:当容器创建时,对象被创建
存活:只要容器还在,对象就还存活
销毁:容器销毁,对象也销毁
总结:单例对象的生命周期和容器相同
②多例对象
创建:当使用对象时,spring框架为我们创建bean对象
存活:对象使用过程中一直存活
销毁:当对象长时间不用时,且没有别的对象引用时,有Java的垃圾回收器回收
四、spring的依赖注入
1. 基本概念
依赖注入:Dependency Injection
IoC作用:降低程序间的耦度
依赖关系:都交给spring来维护。在当前类需要用到其他类的对象,由spring为我们提供供,我们只需要在配置文件中说明
依赖注入:在Spring框架下,当Bean实例 A运行过程中需要引用另外一个Bean实例B时,Spring框架会创建Bean的实例B,并将实例B通过实例A的构造函数、set方法、自动装配和注解方式注入到实例A,这种注入实例Bean到另外一个实例Bean的过程称为依赖注入。
2. 注入的类型
- 基本类型
- String
- 其他bean类型(在配置文件中或者注解配置过的bean)
3. 注入方式
- 使用构造方法提供
- 使用set方法提供
- 使用注解提供
4. 使用构造方法提供
① constructor标签
bean标签的子标签
标签属性
type:用于指定要注入的数据的数据类型,该数据类型也是构造方法中的某个或某些参数的类型
index:用于指定要注入的数据给构造方法中指定索引位置的参数赋值。索引的位置是从0开始
name:用于指定给构造方法中指定名称的参数赋值 。(常用)
value:用于提供基本类型和String类型的数据
ref:用于指定其他的bean类型数据。它指的就是在是spring核心容器中出现过的bean
② 优势
在获取bean对象时,注入数据时必须的操作,否则对象无法创建完成。
③ 弊端
改变了bean对象实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
5. 使用set方法提供(更常用)
① property标签
标签属性
name:用于指定给构造方法中指定名称的参数赋值 。
value:用于提供基本类型和String类型的数据
ref:用于指定其他的bean类型数据。它指的就是在是spring核心容器中出现过的bean
② 优势
创建对象时没有明确的限制,可以直接使用默认构造方法。
③ 弊端
如果有某个成员必须有值,则获取对象时set方法无法保证一定注入。
6. 注入集合数据
接口相同,标签可以互换
<!-- 使用集合类型的set方法注入-->
<bean id="accountService3" class="com.hyg.service.impl.AccountServiceImpl3">
<property name="mystrs">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="mylist">
<list>
<value>123</value>
<value>456</value>
<value>789</value>
</list>
</property>
<property name="myset">
<set>
<value>123</value>
<value>456</value>
<value>789</value>
</set>
</property>
<property name="mymap">
<map>
<entry key="test1" value="12"></entry>
<entry key="test2">
<value>123</value>
</entry>
</map>
</property>
<property name="myprops">
<props>
<prop key="testc">verrvr</prop>
<prop key="testd">dfsd</prop>
</props>
</property>
</bean>
五、 基于注解的IoC配置
在xml文件中使用如下标签告知spring在创建容器时要扫描的包,配置所需要的标签不是在beans的约束,而是在context名称空间和约束中。
<context:component-scan base-package="com.hyg"></context:component-scan>
1. 创建对象的注解
① @Component
作用:把当前类对象存入spring容器中
属性:value,用于指定bean的id。默认为当前类名,首字母改小写
作用和在xml配置文件中编写一个标签实现的功能是一样的
② Contorller、Service、Repository
与Component注解的作用和属性一摸一样,spring框架为我们提供明确的三层使用的注解,是我们的三层对象更加清晰。
Contorller:持久层
Service业务层
Repository持久层
2. 注入数据的注解
① @Autowired
作用:自动按照类型注入,只要容器中有唯一的一个bean对象,类型和要注入的变量类型匹配,就可以注入成功。
出现位置:变量、方法
② @Qualifier
作用:在按照类中注入的基础上再按照名称注入,它在给类成员注入时不能单独使用,但是在给方法参数注入时可以。
属性:value,用于指定注入bean的id。
③ @Resource
作用:直接按照bean的id注入。可以独立使用
属性:name,用于指定bean的id
④ @Value
作用:用于注入基本类型和String类型的数据
属性:value:用于指定数据的值。它可以使用spring中的SpEL(spring中的el表达式)
SpEL的写法:${ 表达式 }
注意:
- Autowired、Qualifier、Resource只能注入其他bean类型的数据,不能注入基本类型和String类型
- 集合类型只能通过xml来实现
无法使用
作用和在xml配置文件中编写一个标签实现的功能是一样的
3. 改变作用范围的注解
@Scpoe
作用:用于指定bean的作用范围,和在bean标签中编写一个<scope>标签实现的功能是一样的
属性:value:指定范围的取值。常取值:singleton(单列,默认)、prototype(多例)
4. 生命周期的注解
@PreDestroy:用于指定销毁方法
@PostConstruct:用于指定初始化方法
作用和在bean标签中使用init-method和destroy-method的作用是一样的
5. spring新注解
@Configuraction
- 指定当前类是一个配置类。只有配置了这个注解,spring才会扫描下边的componentscan注解配置的类路径
- 当配置类作为AnnotationConfigApplicationcontext对象创建的参数时,可以不添加该注解
- 要想不适用这个注解,可将该类作为AnnotationConfigApplicationcontext对象创建的参数传入即可
@ComponentScan
作用:用于通过注解指定spring在创建容器时要扫描的包
属性:value==basePackages,和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。
如同: <context:component-scan base-package=“com.hyg”></context:component-scan>
@Bean
作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中
属性:name,用于指定bean的id。不写时,默认值为当前方法的方法名。
@Scope(“prototype”)
和@Bean配合使用,指定为多例
@Import
作用:可以引用其他没有配置Configuraction注解的配置类字节码文件。
属性:value
有Import注解的类是父配置类,被导入的配置类为子配置类
@PropertySource
作用:指定properties文件的位置
属性:value,指定文件的名称和路径,关键字classpath,表示类路径下
@PropertySource(“classpath:jdbcConfig.properties”)
作用:指定properties文件的位置
属性:value,指定文件的名称和路径,关键字classpath,表示类路径下
@PropertySource("classpath:jdbcConfig.properties")