文章目录
- 一、spring概述
- 二、spring的模块介绍
- 3、IOC的依赖注入
- 三、springHolleWorld
- 3.1 通过id获取对象
- 3.2 通过类型获取对象
- 3.3 通过构造方法参数名注入值
- 3.4 IOC之 P名称空间
- 3.5 测试null值的使用
- 3.6 IOC之子对象的赋值测试
- 3.7 IOC之内部Bean的使用
- 3.8 IOC之List属性的赋值
- 3.9 IOC之Map属性的赋值
- 3.10 IOC之Properties属性的赋值
- 3.11 IOC之util 名称空间
- 3.12 IOC之级联属性赋值
- 3.13 IOC之静态工厂方法/工厂实例方法创建创建Bean
- 3.14 IOC之FactoryBean接口方式创建对象
- 3.15 IOC之继承Bean配置及抽象Bean
- 3.16 spring容器内的Bean默认创建顺序
- 3.17 IOC之Bean的单例和多例
- 3.18 基于xml配置文件的自动注入
- 四、Bean的生命周期
- 五、Spring管理数据库连接池(重点)
- 一、spring概述
- 二、spring的模块介绍
- 3、IOC的依赖注入
- 三、springHolleWorld
- 3.1 通过id获取对象
- 3.2 通过类型获取对象
- 3.3 通过构造方法参数名注入值
- 3.4 IOC之 P名称空间
- 3.5 测试null值的使用
- 3.6 IOC之子对象的赋值测试
- 3.7 IOC之内部Bean的使用
- 3.8 IOC之List属性的赋值
- 3.9 IOC之Map属性的赋值
- 3.10 IOC之Properties属性的赋值
- 3.11 IOC之util 名称空间
- 3.12 IOC之级联属性赋值
- 3.13 IOC之静态工厂方法/工厂实例方法创建创建Bean
- 3.14 IOC之FactoryBean接口方式创建对象
- 3.15 IOC之继承Bean配置及抽象Bean
- 3.16 spring容器内的Bean默认创建顺序
- 3.17 IOC之Bean的单例和多例
- 3.18 基于xml配置文件的自动注入
- 四、Bean的生命周期
- 五、Spring管理数据库连接池(重点)
一、spring概述
①spring是一个开源框架
②Spring为简化企业级开发而生,使用Spring开发可以将Bean对象,Dao组件对象,Service组件对象等交给Spring容器来管理,这样使得很多复杂的代码在Spring中开发却变得非常的优雅和简洁,有效的降低代码的耦合度,极大的方便项目的后期维护、升级和扩展。
③Spring是一个IOC(DI)和AOP容器框架。
④Spring的优良特性
[1]非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API
[2]控制反转:IOC——Inversion of Control,指的是将对象的创建权交给Spring去创建。使用Spring之前,对象的创建都是由我们自己在代码中new创建。而使用Spring之后。对象的创建都是由给了Spring框架。
[3]依赖注入:DI——Dependency Injection,是指依赖的对象不需要手动调用setXX方法去设置,而是通过配置赋值。
[4]面向切面编程:Aspect Oriented Programming——AOP
[5]容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期
[6]组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。
[7]一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)
二、spring的模块介绍
Spring框架分为四大模块:
Core核心模块。负责管理组件的Bean对象
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
面向切面编程
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
数据库操作
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-oxm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar
spring-jms-4.0.0.RELEASE.jar
Web模块
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
spring-websocket-4.0.0.RELEASE.jar
spring-webmvc-portlet-4.0.0.RELEASE.jar
3、IOC的依赖注入
3.1IOC
IOC 全称指的是 Inverse Of Control 控制反转。
在使用Spring之前,对象的创建是由我们自己在代码中去new而产生。
而使用了spring之后。对象的创建完全交由Spring容器来进行。
注意:如果是你自己new的对象,就不会自动Spring的功能。
3.2 DI
DI 指的是Dependency Injection 。是依赖注入的意思。
依赖,是指,一个对象需要完成某个功能,然后必须依靠另一个对象。叫依赖。
简单点说,就是需要。就是依赖。
比如:
public class BookService {
private BookDao bookDao; // BookService依赖BookDao
}
注入,就是给对象赋值。
依赖注入,就是指给依赖的对象赋值操作。叫依赖注入。
在使用Spring框架之前,依赖对象的赋值都是由我们通过构造器方法,或者setXxx方法来进行设置。
在使用Spring框架之后,只需要通过xml配置,或者是注解配置就可以对依赖的对象进行方法,即可的方便后面的维护和扩展
三、springHolleWorld
1.导入jar包
junit_4.12.jar
org.hamcrest.core_1.3.0.jar
spring-beans-5.2.5.RELEASE.jar
spring-context-5.2.5.RELEASE.jar
spring-core-5.2.5.RELEASE.jar
spring-expression-5.2.5.RELEASE.jar
spring-jcl-5.2.5.RELEASE.jar
2.创建javaBean类
public class Person {
private Integer id;
private String name;
private String sex;
private Phone phone;
private List<String> list;
private Map<String,Object> map;
3.在src目录下创建springconfig文件-applictionCotext.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 http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd https://www.springframework.org/schema/context/spring-context.xsd">
</beans>
3.1 通过id获取对象
4.在applictionContext.xml中配置
<!--
bean:表示配置一个对象
id:唯一值,方便引用
class:对象的类型,设置全类名
property:
name:对象的属性
value:对对象的属性赋值
-->
<bean id="p1" class="com.atguigu.pojo.Person">
<property name="id" value="1"/>
<property name="name" value="spring中的实例1"/>
<property name="sex" value="男"/>
</bean>
test测试类
@Test
public void Test() {
/*
如何使用Spring,首先要先有一个Spring的容器对象
在Spring中容器对象由接口 ApplicationContext 表示。
ClassPathXmlApplicationContext表示从classpath类路径下加载xml配置文件,
生成ApplicationContext容器对象
*/
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applictionContext.xml");
Person p1 = (Person) applicationContext.getBean("p1");
System.out.println(p1);
}
3.2 通过类型获取对象
@Test
public void Test1() {
/*
容易引起的异常,多个同类型
NoUniqueBeanDefinitionException:
No qualifying bean of type 'com.atguigu.pojo.Person'
available: expected single matching bean but found 2: p1,p2
*/
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applictionContext.xml");
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
3.3 通过构造方法参数名注入值
<!--constructor-->
<!--
Person(id,name,sex);
constructor-arg:通过构造器赋值使用属性
-->
<bean id="p3" class="com.atguigu.pojo.Person">
<constructor-arg name="id" value="3"/>
<constructor-arg name="name" value="通过有参构造方法注入参数"/>
<constructor-arg name="sex" value="男"/>
<constructor-arg name="phone"><null></null></constructor-arg>
<constructor-arg name="list"><list></list></constructor-arg>
<constructor-arg name="map"><map></map></constructor-arg>
</bean>
<!--
调用构造器通过index属性指定赋值
-->
<bean class="com.atguigu.pojo.Person" id="p4">
<constructor-arg index="0" value="4"/>
<constructor-arg index="1" value="index注入有参构造"/>
<constructor-arg index="2" value="ppp"/>
<constructor-arg index="3"><null></null></constructor-arg>
<constructor-arg index="4"><null></null></constructor-arg>
<constructor-arg index="5"><null></null></constructor-arg>
</bean>
<!--
(有参构造器)根据参数类型注入
index属性设置构造器参数索引的顺序,从0开始
type属性可以设置参数的具体类型,大多用于函数重载的情况
-->
<bean class="com.atguigu.pojo.Person" id="p5">
<constructor-arg type="java.lang.Integer" value="5"/>
<constructor-arg type="java.lang.String" value="根据参数类型注入"/>
<constructor-arg type="java.lang.String" value="ll"/>
<constructor-arg index="3"><null></null></constructor-arg>
<constructor-arg index="4"><null></null></constructor-arg>
<constructor-arg index="5"><null></null></constructor-arg>
</bean>
3.4 IOC之 P名称空间
引用p标签
xmlns:p=“http://www.springframework.org/schema/p”
<bean class="com.atguigu.pojo.Person" id="p6"
p:id="6" p:name="p名称空间注入" p:sex="p"/>
3.5 测试null值的使用
<constructor-arg index="5"><null></null></constructor-arg>
或
<property name="phone"><null></null></property>
3.6 IOC之子对象的赋值测试
子对象JavaBean
public class Phone {
private String brand;
private Double money;
applictionContext.xml
<!--================================子对象赋值=============================================-->
<!--
子对象赋值
ps:引用Bean的方法可以在spring容器中通过id获取手机Bean;
使用内部Bean的方式给子对象赋值 spring容器无法通过id得到PhoneBean
NoSuchBeanDefinitionException: No bean named 'phone' available
-->
<!--
1.引用对象
1.1先创建phone Bean
1.2创建person Bean phone属性 用 ref属性引入phone
ref="id"
<bean id="phone" class="com.atguigu.pojo.Phone">
<property name="brand" value="爱疯四"/>
<property name="money" value="2999.9"/>
</bean>
<bean id="p8" class="com.atguigu.pojo.Person">
<property name="phone" ref="phone"/>
</bean>
-->
3.7 IOC之内部Bean的使用
<!--
内部bean的使用
使用内部Bean的方式给子对象赋值 spring容器无法通过id得到PhoneBean
NoSuchBeanDefinitionException: No bean named 'phone' available
-->
<bean id="p8" class="com.atguigu.pojo.Person">
<property name="id" value="8"/>
<property name="phone">
<bean class="com.atguigu.pojo.Phone">
<property name="brand" value="爱疯四"/>
<property name="money" value="2999.9"/>
</bean>
</property>
</bean>
<!--
3.8 IOC之List属性的赋值
<!--================================使用List子标签为List赋值=================================-->
<!--
list赋值
list标签:一个列表可以包含多个内部bean,ref,collection或value元素。
列表也可以映射到数组类型。 进行必要的转换 自动
每一个value标签都是list里的值
-->
<bean id="p9" class="com.atguigu.pojo.Person">
<property name="list">
<list>
<value>朱茵</value>
<value>王祖贤</value>
<value>宋美龄</value>
<value>奥戴尔·赫本</value>
</list>
</property>
</bean>
<!--======================================================================================-->
3.9 IOC之Map属性的赋值
<!--============================使用Map子标签为List赋值======================================-->
<!--
map: 键值对
entry:
key 键
value 值
-->
<bean id="p10" class="com.atguigu.pojo.Person">
<property name="map">
<map key-type="java.lang.String" value-type="java.lang.Object">
<entry key="v1" value="k1"/>
<entry key="v2" value="k2"/>
<entry key="v3" value="k3"/>
</map>
</property>
</bean>
3.10 IOC之Properties属性的赋值
<!--===============================使用props标签为properties属性赋值==========================-->
<bean id="p11" class="com.atguigu.pojo.Person">
<property name="props">
<props>
<prop key="url">jdbc:mysql:///test</prop>
<prop key="userName">root</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
<!--======================================================================================-->
3.11 IOC之util 名称空间
<!--
前面的集合都是在Bean内部赋值给对象属性的,spring容器无法直接获取
而util名称空间,可以定义spring容器直接获取,引用的集合数据
-->
<util:list id="list1">
<value>迪丽热巴</value>
<value>赵丽颖</value>
<value>古力娜扎</value>
</util:list>
<bean id="p12" class="com.atguigu.pojo.Person">
<property name="list" ref="list1"/>
</bean>
3.12 IOC之级联属性赋值
<!--
级联属性:
一定要先注入对象,在注入对象的属性
-->
<bean id="phone1" class="com.atguigu.pojo.Phone">
</bean>
<bean id="p13" class="com.atguigu.pojo.Person">
<property name="name" value="级联属性"/>
<property name="phone" ref="phone1"/>
<property name="phone.money" value="3999.9"/>
<property name="phone.brand" value="华威40保斯捷"/>
</bean>
3.13 IOC之静态工厂方法/工厂实例方法创建创建Bean
public class PersonFactory {
public static Person getStaticPerson(){
return new Person(14, "静态工厂方法创建Person", null,null,null,null);
}
public Person getPerson(){
return new Person(14, "实例工厂方法创建Person", null,null,null,null);
}
}
applictionContext.xml
<!--
工厂创建对象
1.静态工厂创建
<bean id="p14" class="com.atguigu.pojo.PersonFactory"
factory-method="getStaticPerson" />
2.实例工厂创建
先实例化工厂,在调用getPerson方法
<bean class="com.atguigu.pojo.PersonFactory" id="factory"/>
<bean id="p14" class="com.atguigu.pojo.PersonFactory" factory-bean="factory"
factory-method="getPerson"/>
-->
3.14 IOC之FactoryBean接口方式创建对象
public class FactoryBeanImpl implements FactoryBean<Person> {
@Override
public Person getObject() throws Exception {
return new Person(15, "通过继承FactoryBean接口方式创建的对象", null,null,null,null);
}
@Override
public Class<?> getObjectType() {
return Person.class;
}
}
applictionContext.xml
<!--
通过继承FactoryBean<T>接口的类创建Bean
-->
<bean id="p15" class="com.atguigu.pojo.FactoryBeanImpl"/>
3.15 IOC之继承Bean配置及抽象Bean
<!--==============================继承及抽象=======================================-->
<!--
abstract="true"
当父类设置abstract属性为true时 子类无法继承 出错
Error creating bean with name 'parent': Bean definition is abstract
-->
<!--父-->
<!-- <bean id="parent" class="com.atguigu.pojo.Person" abstract="true">-->
<bean id="parent" class="com.atguigu.pojo.Person" >
<property name="id" value="16"/>
<property name="name" value="我是爹"/>
<property name="phone">
<bean class="com.atguigu.pojo.Phone">
<property name="brand" value="爱疯四"/>
<property name="money" value="2999.9"/>
</bean>
</property>
</bean>
<!--子-->
<bean id="p16" class="com.atguigu.pojo.Person" parent="parent">
<property name="name" value="我是老baby"/>
<property name="phone">
<bean class="com.atguigu.pojo.Phone">
<property name="brand" value="爱疯六"/>
<property name="money" value="9999.9"/>
</bean>
</property>
</bean>
<!--========================================================================-->
3.16 spring容器内的Bean默认创建顺序
<!--========================Bean的创建顺序===================================-->
<!--
默认创建顺序
A创建了
B创建了
C创建了 由此可见 IOC中的bean默认时xxx.xml文件中自上而下的顺序创建的
depends-on="b" 在此Bean注册之前先注册id为"b"的bean
-->
<bean id="a" class="com.atguigu.pojo.A" depends-on="b"/>
<bean id="b" class="com.atguigu.pojo.B"/>
<bean id="c" class="com.atguigu.pojo.C"/>
<!--=======================================================================-->
3.17 IOC之Bean的单例和多例
<!--
ioc中 默认创建单例 引用地址存储在spring容器中 随着spring容器创建销毁
scope:
singleton:
默认单例(多次调用返回同一个Bean)
随着spring容器的创建而创建
prototype
多例(每次调用都是不同的Bean)
不随着spring容器的创建而创建
-->
<bean id="p19" class="com.atguigu.pojo.Person" scope="prototype">
<property name="name" value="ppp"/>
<property name="id" value="111"/>
<property name="sex" value="x"/>
</bean>
3.18 基于xml配置文件的自动注入
<!--
autowire
byName:
1.根据子对象的属性名来匹配符合id的Bean 找到了一个就赋值
public class Person {
private Phone phone;//查找id为phone的bean
2.找不到则为null
byType:
1.根据子对象的类型类匹配Bean 找到了一个就赋值
2.找到多个则报错 //org.springframework.beans.factory.
UnsatisfiedDependencyException:
Unsatisfied dependency expressed through bean property 'phone'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.atguigu.pojo.Phone' available: expected single matching bean but found 2: phone1,phone4
3.找不到为null
constructor:1.根据子对象的类型类匹配Bean 找到了
-->
<bean id="phone4" class="com.atguigu.pojo.Phone">
<property name="brand" value="phoneByname"/>
<property name="money" value="2000"/>
</bean>
<bean id="phone" class="com.atguigu.pojo.Phone">
<property name="brand" value="constructor"/>
<property name="money" value="8000"/>
</bean>
<bean id = "p20" class="com.atguigu.pojo.Person" autowire="constructor">
<property name="id" value="20"/>
</bean>
四、Bean的生命周期
1. IOC之Bean的生命周期
创建一个类Life
public void init(){
System.out.println(" 对象初始化了 ");
}
public void destory(){
System.out.println(" 对象销毁了 ");
}
appliction.xml
<!--
init-method:在对象创建之后执行
destroy-method:在对象销毁后执行(对多例无效)
-->
<bean id="life" class="com.atguigu.pojo.Life" scope="prototype"
init-method="init" destroy-method="destroy"/>
默认情况下。Spring配置文件中的对象会随着Spring容器的创建而一起创建.
关闭Spring 容器的时候,才会销毁Bean对象(对多例无效)
2.Bean对象的后置处理器
创建类继承BeanPostProcessor接口
package com.atguigu.beanpostprocessor;
import com.atguigu.pojo.Customer;
import com.atguigu.pojo.Phone;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @author ikkkc_
* @Data 2020-12-29 周二
* @Description
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
// bean的后置处理器
//初始化前
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("==postProcessBeforeInitialization==");
System.out.println("正在初始化的对象" + bean);
System.out.println("正在初始化的对象的名称" + beanName);
System.out.println("==postProcessBeforeInitialization==");
return bean;
}
//初始化后
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("=======postProcessAfterInitialization========");
if (bean instanceof Customer) {
Customer beanT = (Customer) bean;
beanT.setPhone(new Phone("爱疯888", 3999.9));
}
return bean;
}
}
applictionContext.xml
<!-- 配置后置处理器实例(任何一个在Spring容器创建初始化的对象,都会经过它的处理) -->
<bean class="com.atguigu.beanpostprocessor.MyBeanPostProcessor"/>
<bean id="p22" class="com.atguigu.pojo.Customer">
<property name="id" value="22"/>
</bean>
五、Spring管理数据库连接池(重点)
导入需要的jar包:
druid-1.1.9.jar
mysql-connector-java-5.1.37-bin.jar
1.连接数据库
<!-- 连接数据库-->
<bean id="datasource1" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="jdbc:mysql:///mybatis"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<property name="maxActive" value="10"/>
<property name="initialSize" value="5"/>
</bean>
测试
@Test
public void Test23() throws SQLException {
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applictionContext.xml");
DruidDataSource datasource1 = (DruidDataSource) applicationContext.getBean("datasource1");
System.out.println(datasource1);
System.out.println(datasource1.getConnection());
}
2.Spring引入单独的jdbc.properties配置文件(重点)
jdbc.properties
url=jdbc:mysql:///mybatis
driverClassName=com.mysql.jdbc.Driver
#spring的username用的时登录名的name 请用别的值代替
user=root
password=123456
maxActive=10
initialSize=5
applictionContext.xml
<!-- 通过props加载配置文件连接数据库
注意 : username在spring中有别的含义,请在配置文件中取别的名字-->
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<!--
加载配置文件
location:设置加载文件路径
classpath:从类的路径加载文件
-->
<property name="location" value="classpath:jdbc.properties"/>
</bean>
<bean id="datasource2" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${url}"/>
<property name="driverClassName" value="${driverClassName}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
<property name="maxActive" value="${maxActive}"/>
<property name="initialSize" value="${initialSize}"/>
</bean>
3.使用context名称空间加载jdbc.properties配置文件(重点)
<!--context名称空间加载配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="datasource3" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${url}"/>
<property name="driverClassName" value="${driverClassName}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
<property name="maxActive" value="${maxActive}"/>
<property name="initialSize" value="${initialSize}"/>
</bean>
一、spring概述
①spring是一个开源框架
②Spring为简化企业级开发而生,使用Spring开发可以将Bean对象,Dao组件对象,Service组件对象等交给Spring容器来管理,这样使得很多复杂的代码在Spring中开发却变得非常的优雅和简洁,有效的降低代码的耦合度,极大的方便项目的后期维护、升级和扩展。
③Spring是一个IOC(DI)和AOP容器框架。
④Spring的优良特性
[1]非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API
[2]控制反转:IOC——Inversion of Control,指的是将对象的创建权交给Spring去创建。使用Spring之前,对象的创建都是由我们自己在代码中new创建。而使用Spring之后。对象的创建都是由给了Spring框架。
[3]依赖注入:DI——Dependency Injection,是指依赖的对象不需要手动调用setXX方法去设置,而是通过配置赋值。
[4]面向切面编程:Aspect Oriented Programming——AOP
[5]容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期
[6]组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。
[7]一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)
二、spring的模块介绍
Spring框架分为四大模块:
Core核心模块。负责管理组件的Bean对象
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
面向切面编程
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
数据库操作
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-oxm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar
spring-jms-4.0.0.RELEASE.jar
Web模块
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
spring-websocket-4.0.0.RELEASE.jar
spring-webmvc-portlet-4.0.0.RELEASE.jar
3、IOC的依赖注入
3.1IOC
IOC 全称指的是 Inverse Of Control 控制反转。
在使用Spring之前,对象的创建是由我们自己在代码中去new而产生。
而使用了spring之后。对象的创建完全交由Spring容器来进行。
注意:如果是你自己new的对象,就不会自动Spring的功能。
3.2 DI
DI 指的是Dependency Injection 。是依赖注入的意思。
依赖,是指,一个对象需要完成某个功能,然后必须依靠另一个对象。叫依赖。
简单点说,就是需要。就是依赖。
比如:
public class BookService {
private BookDao bookDao; // BookService依赖BookDao
}
注入,就是给对象赋值。
依赖注入,就是指给依赖的对象赋值操作。叫依赖注入。
在使用Spring框架之前,依赖对象的赋值都是由我们通过构造器方法,或者setXxx方法来进行设置。
在使用Spring框架之后,只需要通过xml配置,或者是注解配置就可以对依赖的对象进行方法,即可的方便后面的维护和扩展
三、springHolleWorld
1.导入jar包
junit_4.12.jar
org.hamcrest.core_1.3.0.jar
spring-beans-5.2.5.RELEASE.jar
spring-context-5.2.5.RELEASE.jar
spring-core-5.2.5.RELEASE.jar
spring-expression-5.2.5.RELEASE.jar
spring-jcl-5.2.5.RELEASE.jar
2.创建javaBean类
public class Person {
private Integer id;
private String name;
private String sex;
private Phone phone;
private List<String> list;
private Map<String,Object> map;
3.在src目录下创建springconfig文件-applictionCotext.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 http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd https://www.springframework.org/schema/context/spring-context.xsd">
</beans>
3.1 通过id获取对象
4.在applictionContext.xml中配置
<!--
bean:表示配置一个对象
id:唯一值,方便引用
class:对象的类型,设置全类名
property:
name:对象的属性
value:对对象的属性赋值
-->
<bean id="p1" class="com.atguigu.pojo.Person">
<property name="id" value="1"/>
<property name="name" value="spring中的实例1"/>
<property name="sex" value="男"/>
</bean>
test测试类
@Test
public void Test() {
/*
如何使用Spring,首先要先有一个Spring的容器对象
在Spring中容器对象由接口 ApplicationContext 表示。
ClassPathXmlApplicationContext表示从classpath类路径下加载xml配置文件,
生成ApplicationContext容器对象
*/
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applictionContext.xml");
Person p1 = (Person) applicationContext.getBean("p1");
System.out.println(p1);
}
3.2 通过类型获取对象
@Test
public void Test1() {
/*
容易引起的异常,多个同类型
NoUniqueBeanDefinitionException:
No qualifying bean of type 'com.atguigu.pojo.Person'
available: expected single matching bean but found 2: p1,p2
*/
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applictionContext.xml");
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
3.3 通过构造方法参数名注入值
<!--constructor-->
<!--
Person(id,name,sex);
constructor-arg:通过构造器赋值使用属性
-->
<bean id="p3" class="com.atguigu.pojo.Person">
<constructor-arg name="id" value="3"/>
<constructor-arg name="name" value="通过有参构造方法注入参数"/>
<constructor-arg name="sex" value="男"/>
<constructor-arg name="phone"><null></null></constructor-arg>
<constructor-arg name="list"><list></list></constructor-arg>
<constructor-arg name="map"><map></map></constructor-arg>
</bean>
<!--
调用构造器通过index属性指定赋值
-->
<bean class="com.atguigu.pojo.Person" id="p4">
<constructor-arg index="0" value="4"/>
<constructor-arg index="1" value="index注入有参构造"/>
<constructor-arg index="2" value="ppp"/>
<constructor-arg index="3"><null></null></constructor-arg>
<constructor-arg index="4"><null></null></constructor-arg>
<constructor-arg index="5"><null></null></constructor-arg>
</bean>
<!--
(有参构造器)根据参数类型注入
index属性设置构造器参数索引的顺序,从0开始
type属性可以设置参数的具体类型,大多用于函数重载的情况
-->
<bean class="com.atguigu.pojo.Person" id="p5">
<constructor-arg type="java.lang.Integer" value="5"/>
<constructor-arg type="java.lang.String" value="根据参数类型注入"/>
<constructor-arg type="java.lang.String" value="ll"/>
<constructor-arg index="3"><null></null></constructor-arg>
<constructor-arg index="4"><null></null></constructor-arg>
<constructor-arg index="5"><null></null></constructor-arg>
</bean>
3.4 IOC之 P名称空间
引用p标签
xmlns:p=“http://www.springframework.org/schema/p”
<bean class="com.atguigu.pojo.Person" id="p6"
p:id="6" p:name="p名称空间注入" p:sex="p"/>
3.5 测试null值的使用
<constructor-arg index="5"><null></null></constructor-arg>
或
<property name="phone"><null></null></property>
3.6 IOC之子对象的赋值测试
子对象JavaBean
public class Phone {
private String brand;
private Double money;
applictionContext.xml
<!--================================子对象赋值=============================================-->
<!--
子对象赋值
ps:引用Bean的方法可以在spring容器中通过id获取手机Bean;
使用内部Bean的方式给子对象赋值 spring容器无法通过id得到PhoneBean
NoSuchBeanDefinitionException: No bean named 'phone' available
-->
<!--
1.引用对象
1.1先创建phone Bean
1.2创建person Bean phone属性 用 ref属性引入phone
ref="id"
<bean id="phone" class="com.atguigu.pojo.Phone">
<property name="brand" value="爱疯四"/>
<property name="money" value="2999.9"/>
</bean>
<bean id="p8" class="com.atguigu.pojo.Person">
<property name="phone" ref="phone"/>
</bean>
-->
3.7 IOC之内部Bean的使用
<!--
内部bean的使用
使用内部Bean的方式给子对象赋值 spring容器无法通过id得到PhoneBean
NoSuchBeanDefinitionException: No bean named 'phone' available
-->
<bean id="p8" class="com.atguigu.pojo.Person">
<property name="id" value="8"/>
<property name="phone">
<bean class="com.atguigu.pojo.Phone">
<property name="brand" value="爱疯四"/>
<property name="money" value="2999.9"/>
</bean>
</property>
</bean>
<!--
3.8 IOC之List属性的赋值
<!--================================使用List子标签为List赋值=================================-->
<!--
list赋值
list标签:一个列表可以包含多个内部bean,ref,collection或value元素。
列表也可以映射到数组类型。 进行必要的转换 自动
每一个value标签都是list里的值
-->
<bean id="p9" class="com.atguigu.pojo.Person">
<property name="list">
<list>
<value>朱茵</value>
<value>王祖贤</value>
<value>宋美龄</value>
<value>奥戴尔·赫本</value>
</list>
</property>
</bean>
<!--======================================================================================-->
3.9 IOC之Map属性的赋值
<!--============================使用Map子标签为List赋值======================================-->
<!--
map: 键值对
entry:
key 键
value 值
-->
<bean id="p10" class="com.atguigu.pojo.Person">
<property name="map">
<map key-type="java.lang.String" value-type="java.lang.Object">
<entry key="v1" value="k1"/>
<entry key="v2" value="k2"/>
<entry key="v3" value="k3"/>
</map>
</property>
</bean>
3.10 IOC之Properties属性的赋值
<!--===============================使用props标签为properties属性赋值==========================-->
<bean id="p11" class="com.atguigu.pojo.Person">
<property name="props">
<props>
<prop key="url">jdbc:mysql:///test</prop>
<prop key="userName">root</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
<!--======================================================================================-->
3.11 IOC之util 名称空间
<!--
前面的集合都是在Bean内部赋值给对象属性的,spring容器无法直接获取
而util名称空间,可以定义spring容器直接获取,引用的集合数据
-->
<util:list id="list1">
<value>迪丽热巴</value>
<value>赵丽颖</value>
<value>古力娜扎</value>
</util:list>
<bean id="p12" class="com.atguigu.pojo.Person">
<property name="list" ref="list1"/>
</bean>
3.12 IOC之级联属性赋值
<!--
级联属性:
一定要先注入对象,在注入对象的属性
-->
<bean id="phone1" class="com.atguigu.pojo.Phone">
</bean>
<bean id="p13" class="com.atguigu.pojo.Person">
<property name="name" value="级联属性"/>
<property name="phone" ref="phone1"/>
<property name="phone.money" value="3999.9"/>
<property name="phone.brand" value="华威40保斯捷"/>
</bean>
3.13 IOC之静态工厂方法/工厂实例方法创建创建Bean
public class PersonFactory {
public static Person getStaticPerson(){
return new Person(14, "静态工厂方法创建Person", null,null,null,null);
}
public Person getPerson(){
return new Person(14, "实例工厂方法创建Person", null,null,null,null);
}
}
applictionContext.xml
<!--
工厂创建对象
1.静态工厂创建
<bean id="p14" class="com.atguigu.pojo.PersonFactory"
factory-method="getStaticPerson" />
2.实例工厂创建
先实例化工厂,在调用getPerson方法
<bean class="com.atguigu.pojo.PersonFactory" id="factory"/>
<bean id="p14" class="com.atguigu.pojo.PersonFactory" factory-bean="factory"
factory-method="getPerson"/>
-->
3.14 IOC之FactoryBean接口方式创建对象
public class FactoryBeanImpl implements FactoryBean<Person> {
@Override
public Person getObject() throws Exception {
return new Person(15, "通过继承FactoryBean接口方式创建的对象", null,null,null,null);
}
@Override
public Class<?> getObjectType() {
return Person.class;
}
}
applictionContext.xml
<!--
通过继承FactoryBean<T>接口的类创建Bean
-->
<bean id="p15" class="com.atguigu.pojo.FactoryBeanImpl"/>
3.15 IOC之继承Bean配置及抽象Bean
<!--==============================继承及抽象=======================================-->
<!--
abstract="true"
当父类设置abstract属性为true时 子类无法继承 出错
Error creating bean with name 'parent': Bean definition is abstract
-->
<!--父-->
<!-- <bean id="parent" class="com.atguigu.pojo.Person" abstract="true">-->
<bean id="parent" class="com.atguigu.pojo.Person" >
<property name="id" value="16"/>
<property name="name" value="我是爹"/>
<property name="phone">
<bean class="com.atguigu.pojo.Phone">
<property name="brand" value="爱疯四"/>
<property name="money" value="2999.9"/>
</bean>
</property>
</bean>
<!--子-->
<bean id="p16" class="com.atguigu.pojo.Person" parent="parent">
<property name="name" value="我是老baby"/>
<property name="phone">
<bean class="com.atguigu.pojo.Phone">
<property name="brand" value="爱疯六"/>
<property name="money" value="9999.9"/>
</bean>
</property>
</bean>
<!--========================================================================-->
3.16 spring容器内的Bean默认创建顺序
<!--========================Bean的创建顺序===================================-->
<!--
默认创建顺序
A创建了
B创建了
C创建了 由此可见 IOC中的bean默认时xxx.xml文件中自上而下的顺序创建的
depends-on="b" 在此Bean注册之前先注册id为"b"的bean
-->
<bean id="a" class="com.atguigu.pojo.A" depends-on="b"/>
<bean id="b" class="com.atguigu.pojo.B"/>
<bean id="c" class="com.atguigu.pojo.C"/>
<!--=======================================================================-->
3.17 IOC之Bean的单例和多例
<!--
ioc中 默认创建单例 引用地址存储在spring容器中 随着spring容器创建销毁
scope:
singleton:
默认单例(多次调用返回同一个Bean)
随着spring容器的创建而创建
prototype
多例(每次调用都是不同的Bean)
不随着spring容器的创建而创建
-->
<bean id="p19" class="com.atguigu.pojo.Person" scope="prototype">
<property name="name" value="ppp"/>
<property name="id" value="111"/>
<property name="sex" value="x"/>
</bean>
3.18 基于xml配置文件的自动注入
<!--
autowire
byName:
1.根据子对象的属性名来匹配符合id的Bean 找到了一个就赋值
public class Person {
private Phone phone;//查找id为phone的bean
2.找不到则为null
byType:
1.根据子对象的类型类匹配Bean 找到了一个就赋值
2.找到多个则报错 //org.springframework.beans.factory.
UnsatisfiedDependencyException:
Unsatisfied dependency expressed through bean property 'phone'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.atguigu.pojo.Phone' available: expected single matching bean but found 2: phone1,phone4
3.找不到为null
constructor:1.根据子对象的类型类匹配Bean 找到了
-->
<bean id="phone4" class="com.atguigu.pojo.Phone">
<property name="brand" value="phoneByname"/>
<property name="money" value="2000"/>
</bean>
<bean id="phone" class="com.atguigu.pojo.Phone">
<property name="brand" value="constructor"/>
<property name="money" value="8000"/>
</bean>
<bean id = "p20" class="com.atguigu.pojo.Person" autowire="constructor">
<property name="id" value="20"/>
</bean>
四、Bean的生命周期
1. IOC之Bean的生命周期
创建一个类Life
public void init(){
System.out.println(" 对象初始化了 ");
}
public void destory(){
System.out.println(" 对象销毁了 ");
}
appliction.xml
<!--
init-method:在对象创建之后执行
destroy-method:在对象销毁后执行(对多例无效)
-->
<bean id="life" class="com.atguigu.pojo.Life" scope="prototype"
init-method="init" destroy-method="destroy"/>
默认情况下。Spring配置文件中的对象会随着Spring容器的创建而一起创建.
关闭Spring 容器的时候,才会销毁Bean对象(对多例无效)
2.Bean对象的后置处理器
创建类继承BeanPostProcessor接口
package com.atguigu.beanpostprocessor;
import com.atguigu.pojo.Customer;
import com.atguigu.pojo.Phone;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @author ikkkc_
* @Data 2020-12-29 周二
* @Description
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
// bean的后置处理器
//初始化前
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("==postProcessBeforeInitialization==");
System.out.println("正在初始化的对象" + bean);
System.out.println("正在初始化的对象的名称" + beanName);
System.out.println("==postProcessBeforeInitialization==");
return bean;
}
//初始化后
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("=======postProcessAfterInitialization========");
if (bean instanceof Customer) {
Customer beanT = (Customer) bean;
beanT.setPhone(new Phone("爱疯888", 3999.9));
}
return bean;
}
}
applictionContext.xml
<!-- 配置后置处理器实例(任何一个在Spring容器创建初始化的对象,都会经过它的处理) -->
<bean class="com.atguigu.beanpostprocessor.MyBeanPostProcessor"/>
<bean id="p22" class="com.atguigu.pojo.Customer">
<property name="id" value="22"/>
</bean>
五、Spring管理数据库连接池(重点)
导入需要的jar包:
druid-1.1.9.jar
mysql-connector-java-5.1.37-bin.jar
1.连接数据库
<!-- 连接数据库-->
<bean id="datasource1" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="jdbc:mysql:///mybatis"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<property name="maxActive" value="10"/>
<property name="initialSize" value="5"/>
</bean>
测试
@Test
public void Test23() throws SQLException {
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applictionContext.xml");
DruidDataSource datasource1 = (DruidDataSource) applicationContext.getBean("datasource1");
System.out.println(datasource1);
System.out.println(datasource1.getConnection());
}
2.Spring引入单独的jdbc.properties配置文件(重点)
jdbc.properties
url=jdbc:mysql:///mybatis
driverClassName=com.mysql.jdbc.Driver
#spring的username用的时登录名的name 请用别的值代替
user=root
password=123456
maxActive=10
initialSize=5
applictionContext.xml
<!-- 通过props加载配置文件连接数据库
注意 : username在spring中有别的含义,请在配置文件中取别的名字-->
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<!--
加载配置文件
location:设置加载文件路径
classpath:从类的路径加载文件
-->
<property name="location" value="classpath:jdbc.properties"/>
</bean>
<bean id="datasource2" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${url}"/>
<property name="driverClassName" value="${driverClassName}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
<property name="maxActive" value="${maxActive}"/>
<property name="initialSize" value="${initialSize}"/>
</bean>
3.使用context名称空间加载jdbc.properties配置文件(重点)
<!--context名称空间加载配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="datasource3" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${url}"/>
<property name="driverClassName" value="${driverClassName}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
<property name="maxActive" value="${maxActive}"/>
<property name="initialSize" value="${initialSize}"/>
</bean>