轻量级JavaEE解决方案。
设计模式?
工厂设计模式
1、概念:通过工厂类,创建对象
2、好处:解耦合
Spring的核心API
- ApplicationContext
1、作用:Spring提供的ApplicationContext这个工厂,用于对象的创建
2、好处:解耦合
- ApplicationContext接口类型
1、接口:屏蔽实现的差异
2、非web环境:ClassPathXmlApplicationCntext
3、web环境:XmlWebApplicationContext
细节分析
1 Spring工厂创建的对象,叫做Bean或者组件(component)
2 Spring工厂的相关方法
获取对象的方法
getBean两种
getBeanDefintionNames:获取配置文件中所有Bean标签的id值
getBeanNamesForType:根据类型获得
containsBeanDefintion:返回布尔值,判断是否存在指定id值的Bean
containsBean
配置文件需要注意的细节
1.只配置class属性
getBean(Person.class)
上述配置有没有id值 全限定类名#0
应用场景:如果这个bean只需要使用一次,可以省略id值
如果这个bean会使用多次获者被其他bean引用则需要设置ID值
2.name属性
作用:用于在Spring的配置文件中,为bean对象定义别名
区别:
1.别名可以定义多个,但是id属性只能有一个值
2.XMl的id属性值,命名要求:必须以字母开头,字母,数字,下划线,连字符,不能使用特殊字符。name使用更灵活,可以使用在特殊命名的场景。
3.引入name属性别名时,containsBeanDefintion和containsBean方法的区别。前者使用别名判断不出来,只能判断id属性;后者可以。
Spring工厂的底层实现原理(简易)
1.Spring框架通过ClassPathXmlApplication工厂读取配置文件applicationContetxt.xml
2.获得bean标签的相关信息 id的值,再通过反射创建对象。
3.反射创建对象底层也是会调用对象自己的构造方法。等效于new Person()
注意:Spring工厂是可以调用对象的私有的构造方法创建对象的。
Spring与日志框架进行整合
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
log4j.rootLogger = debug,console
### 日志输出控制台
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
注入(Injection)
1、什么是注入
通过spring工厂及配置文件,为所创建的对象的成员变量赋值
如何注入
- 类的成员变量提供set get 方法
- 配置spring的配置文件
<bean id="person" name="p" class="com.maple.basic.Person">
<property name="age">
<value>10</value>
</property>
<property name="name">
<value>Jsp</value>
</property>
</bean>
注入的好处
解耦合
注入的原理分析
Spring通过底层调用对象属性对应的set方法,完成成员变量的赋值,这种方式也称之为set注入
1、获取配置文件的bean标签,对象的创建
2、解析property标签,等效于:person.setName("Jsp");
Set注入详解
针对于不同类型
JDK内置类型
1.String+8中基本类型
<value>Jsp</value>
2.数组
<property name="emails">
<list>
<value>[email protected]</value>
<value>[email protected]</value>
</list>
</property>
3.Set集合
4.List集合
5.Map集合
<property name="qqs">
<map>
<entry>
<key><value>Jsp</value></key>
<value>7777272722</value>
</entry>
<entry>
<key><value>Pjs</value></key>
<value>77734242722</value>
</entry>
</map>
</property>
6.Properties类型
<property name="p">
<props>
<prop key="key1">value1</prop>
<prop key="key2">value2</prop>
</props>
</property>
反转控制与依赖注入
反转控制(IOC Inverse of Control)
1、控制:对于成员变量赋值的控制权
2、反转控制:把对于成员变量赋值的控制权,从代码中反转到 Spring工厂和配置文件中完成
好处:解耦合
3、底层实现:工厂设计模式
依赖注入(Dependency Injection DI)
注入:通过Spring的工厂及配置文件,为对象(bean、组件)的成员变量赋值
依赖注入:当一个类需要另一个类时,就意味着依赖,一旦出现依赖,就可以把另一个类作为本类的成员变量,最终通过Spring配置文件进行注入。
好处:解耦合
Spring工厂创建复杂对象的3种方式
1、FactoryBean接口
-
开发步骤
-
实现FactoryBean接口
-
Spring配置文件的配置
# 如果Class中指定的类型是FactoryBean接口的实现类,那么通过id值获取的是这个类所创建的复杂对象 Connection <bean id="conn" class="com.maple.factorybean.ConnectionFactoryBean"/>
-
-
细节
1、如果就像获得FactoryBean类型的对象------ctx.getBean("&conn"),获得的就是ConnectionFactoryBean对象 2、isSingleton方法:根据这个对象的特点,决定返回true(SqlSessionFactory)还是false(Connection) 返回true只会创建一个复杂对象 返回false每一次都会创建新的对像
-
FactroyBean的实现原理
Spring内部运行流程--------典型的接口回调过程 1、通过conn获得ConnectionFactoryBean对象,进而通过instanceof判断出是FactoryBean接口的实现类 2、Spring按照规定getObject()----》Connection 3、返回Connection
-
总结
1、Spring中用于创建复杂对象的一种方式,也是Spring原生提供的。
实例工厂
<bean id="connFactory" class="com.maple.factorybean.ConnectionFactory"/>
<bean id="conn" factory-bean="connFactory" factory-method="getConnection"/>
静态工厂
<bean id="conn" class="com.maple.factorybean.StaticConnectionFactory" factory-method="getConnection"/>
总结
控制Spring工厂创建对象的次数
1、如何控制简单对象的创建次数
1: <bean id="account" scope="singleton" class="com.maple.scope.Account"/>
2: <bean id="account" scope="prototype" class="com.maple.scope.Account"/>
默认singleton,设置scope属性
2、如何控制复杂对象的创建次数
isSingleton方法的返回
return true :只会创建一次
return false:每一次都会创建新的
3、为什么要控制对象的创建次数
好处:节省不必要的内存浪费
- 什么样的对象只创建一次
1、SqlSessionFactory
2、DAO
3、Service
- 什么样的对象每一次都要创建新的
1、Connection
2、SqlSession | Session
3、Controller
Spring工厂高级特性
对象的生命周期
什么是对象的生命周期
指的是一个对象的创建、存活、消亡的一个完整过程
为什么要学习它
由Spring来负责对象的创建、存活、消亡,了解生命周期,更加有利于使用好Spring
生命周期的3个阶段
创建阶段
Spring工厂何时创建对象
-
scope=“singleton”
Spring工厂创建的同时,对象的创建 注意:要在获取对象的时候再创建对象怎么办 lazy-init:懒加载 <bean id="product" scope="singleton" class="com.maple.life.Product" lazy-init="true"/>
-
scope=“prototype”
Spring工厂会在获取对象的同时,创建对象 ctx.getBean()
初始化阶段
Spring工厂在创建完对象后,调用对象的初始化方法,完成对应的初始化操作
1.初始化方法提供:根据需求,提供初始化方法,最终完成初始化操作
2.初始化方法调用:Spring工厂进行调用
-
InitializingBean接口
afterProperitesSet() //根据需求实现的方法,完成初始化操作
-
对象中提供一个普通的方法
public void myInit(){ } //通过配置来让spring工厂找到myInit自定义的初始化方法 <bean id="product" class="xxx.Product" init-method="myInit"/>
-
细节分析
1、如果一个对象即实现InitializingBean接口同时又提供了普通的初始化方法 先执行InitializingBean,然后是普通初始化方法 2、注入一定发生在初始化操作的前面 3、初始化操作: 资源的初始化:数据库,IO,网络。。。
销毁阶段
Spring销毁对象前,会调用对象的销毁方法,完成销毁操作
1、什么时候销毁:ctx.close()
2、销毁方法:根据需求,定义销毁方法,完成销毁,Spring工厂完成调用
-
DisposableBean----destory()方法
-
定一个普通的销毁方法
-
细节
1、销毁方法的操作只适用于scope="singleton"