一、Spring框架
1.1 Spring框架是什么
- Spring是一种容器框架,用于配置各个组件(bean)并且维护各个组件bean之间的关系
- Spring框架可以管理Web层,业务层,DAO层,持久层。
- Spring提倡面向接口编程,配合DI技术可以实现层与层的解耦(主要是WEB层和业务层)
- Spring框架图
老板:不懂spring还来做项目?建议离职一、Spring框架二、装配Bean
1.2 一个简单的spring项目
目录结构
- 引入spring的开发包(最小配置spring.jar以及日志包common-logging.jar)
- 创建spring的一个核心文件ApplicationContext.xml,该文件一般放在src目录下,该文件中引入xsd文件,可以自定义文件名。
TestSpring
|---src
|---com.netease
| |---Service
| |---HelloService.java
| |---ByeService.java
| |---Test
| |---TestService.java
|---ApplicationContext.xml
External Libraries
|--- spring.jar
|--- common-logging.jar
|--- ...
代码详情
package com.netease.Service;
public class HelloService {
private String name;
private ByeService byeService; /** 引用了一个ByeService*/
public String getName() { return name;}
public void setName(String name) { this.name = name;}
public ByeService getByeService() { return byeService;}
public void setByeService(ByeService byeService) { this.byeService = byeService;}
public void sayHello() {
System.out.println("hello "+name);
}
}
package com.netease.Service;
public class ByeService {
private String name;
public String getName() { return name;}
public void setName(String name) {this.name = name;}
public void sayBye() {
System.out.println("Bye " + name);
}
}
package com.netease.Test;
import com.netease.Service.HelloService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestService {
public static void main(String[] args) {
/*通过反射机制,在Spring容器中生成对象*/
/*如果%%.xml放在某个包下,则就变为<包名+文件名>*/
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
HelloService helloService = (HelloService) applicationContext.getBean("helloService");
helloService.sayHello();
helloService.getByeService().sayBye();
}
}
Spring核心容器文件ApplicationContext.xml
- 在容器文件中配置Bean(Bean有可能是以下各种类型service/dao/domain/action/数据源)
- Spring框架加载时,会阅读该容器文件,自动创建一个bean对象,并放入内存
- 学习框架,最重要的就是学习各种配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<--注意Spring如何配置Bean以及如何维护Bean之间的依赖-->
<bean id="helloService" class="com.netease.Service.HelloService">
<--注入属性值-->
<property name="name">
<value>Today</value>
</property>
<--维护Bean之间依赖,ref指向下一个Bean-->
<property name="byeService" ref="byeService"/>
</bean>
<bean id="byeService" class="com.netease.Service.ByeService">
<property name="name">
<value>Yesterday</value>
</property>
</bean>
</beans>
1.3 Spring框架运行原理图
- Spring框架什么时候被加载,Spring中配置的bean怎样被创建,Bean与Bean之间的关系如何维护
老板:不懂spring还来做项目?建议离职一、Spring框架二、装配Bean
1.4 IOC与DI是什么
-
IOC(Inverse Of Controll ) 控制反转:
所谓控制反转就是把创建对象(bean),和维护对象(bean)的关系的权利从程序中转移到spring的容器(applicationContext.xml),而程序本身不再维护.
-
DI(Dependency Injection) 依赖注入:
实际上DI和IOC是同一个概念,Spring设计者认为DI更准确表示Spring核心技术
二、装配Bean
2.1 容纳Bean
ApplicationContext方式
-
ApplicationContext ac = new
ClassPathXmlApplicationContext(“com/netease/bean.xml”)
- 这句话执行时,不仅实例化了该容器,其中配置的所有scope为singleton的bean全部通过反射机制被实例化,scope为prototype的bean不会被实例化
其他三种加载方式
- ClassPathXmlApplicationContext:从类路径中加载。
- FileSystemXmlApplicationContext:从文件系统加载,需要全路径
- XmlWebApplicationContext:从web系统中加载。
好处:预先加载,速度快;缺点:耗内存
Bean的作用域,即scope
Bean工厂方式
-
BeanFactory factory = new XmlBeanFactory(new
ClassPathResource(“com/netease/bean.xml”))
- 这句话执行时,仅实例化了该容器,容器中的bean不被实例化,只有当你使用factory.getBean("***")获取某个bean时,才实例化该bean对应的对象。类似于延迟实例化
- 好处:节约内存;缺点:速度慢
- 一般没有特殊要求,都采用ApplicationContext方式实例化(90%),移动端可采用Bean工厂方式
2.2 Bean生命周期
完整生命周期步骤如下(通常只用到加粗的几步):
- 实例化:程序加载ApplicationContext文件,并把bean(scope=singleton)实例化到内存
- 设置属性:调用set方法设置bean中指定的属性 如果你实现了BeanNameAware接口, 则可以通过BeanName
- 如果你实现了BeanFactoryAware接口,则可以获取BeanFactory
- 如果你实现了ApplicationContextAware接口,则可以获取ApplicationContext
- 如果bean和一个后置处理器关联,则会自动去调用 postProcessBeforeInitialization()方法
- 如果你实现InitializingBean接口,则会调用afterPropertiesSet()方法
- 如果设置了,则可以在bean文件中定义自己的初始化方法init.
-
如果bean和一个后置处理器关联,则会自动去调
postProcessAfterInitialization()方法
- 使用bean 容器关闭
- 可以通过实现DisposableBean接口来调用方法 destory,用来关闭资源等
- 可以在 调用定制的销毁方法destroy
ApplicationContext方式
Bean工厂方式
2.3 装配Bean
2.3.1 什么是装配Bean
告诉容器有哪些Bean以及容器如何使用依赖注入将它们配合在一起。
2.3.2 装配方法
- 在XML进行显式配置
- 在Java中进行显示配置
- 隐式的bean发现机制和自动装配
2.3.3 面向XML的装配方法
2.3.3.1 添加一个Bean
- 基本配置:一个bean ID + 全称类名
<beans>
<bean id="foo" class="...Foo"/>
<bean id="bar" class="...Bar"/>
</beans>
- scope属性
<beans>
<bean id="foo" scope="prototype/singleton" class="...Foo"/>
<bean id="bar" class="...Bar"/>
</beans>
注意尽量使用默认的singleton,以防占用太大内存,影响程序性能
init-method 和destroy-method属性
用途:在Spring实例化或者销毁bean时做一些处理工作
使用方法:
- 声明方式:在XML文件中先声明该Bean拥有的初始化和销毁方法的函数名。在bean.java中实现init和destroy方法,函数名可自定义
- 标签方式:不需要在xml文件中声明初始化和销毁方法,在bean.java中采用标签方式声明初始化和销毁方法
@PostConstruct
public void ini(){…}
@PreDestroy
public void destroy(){…}
其他进行初始化和销毁处理的方法:
Spring还提供了两个接口供bean.java使用,来进行实例化或者销毁时的处理,但不推荐
2.3.3.2 通过set方法注入属性和依赖
通过元素的子元素注入属性和依赖
- 注入简单属性(基本类型和String)
<bean id="foo" class="...Foo">
<property name="name">
<value>tom</value>
</property>
</bean>
注入依赖
- 引用其他的Bean
<bean id="foo" class="...Foo">
<property name="name">
<ref bean="bar">
</property>
</bean>
<bean id="bar" class="...Bar">
</bean>
- 内部bean
<bean id="foo" class="...Foo">
<property name="bar">
<bean class="...Bar">...</bean>
</property>
</bean>
- 注入集合属性(数组,List,Set,Map)
设置null
<property name="barlist">
<null/>
</property>
数组
<-- 给数组注入值 -->
<property name="empName">
<list>
<value>小明</value>
<value>李雷</value>
<value>韩梅梅</value>
</list>
</property>
List
<-- 给list注入值 list 中可以有相等的对象 -->
<property name="empList">
<list>
<ref bean="emp2" />
<ref bean="emp1"/>
<ref bean="emp1"/>
</list>
</property>
Set
<-- 给set注入值 set不能有相同的对象 -->
<property name="empsets">
<set>
<ref bean="emp1" />
<ref bean="emp2"/>
<ref bean="emp2"/>
</set>
</property>
Map
<-- 给map注入值只要key不同即可 -->
<property name="empMaps">
<map>
<entry key="11" value-ref="emp1" />
<entry key="22" value-ref="emp2"/>
<entry key="33" value-ref="emp1"/>
</map>
</property>
property
<property name="pp">
<props>
<prop key="pp1">abcd</prop>
<prop key="pp2">hello</prop>
</props>
</property>
Bean的继承
- public class Student有name和age两个属性
- public class Gradate extends
- Student 有degree属性 在ApplicationContext文件中体现配置
即student中配置过的属性graduate可以不配置 如果配置,则会覆盖父类的属性
<-- 配置一个学生对象 -->
<bean id="student" class="com.hsp.inherit.Student">
<property name="name" value="顺平" />
<property name="age" value="30"/>
</bean>
<-- 配置Grdate对象 -->
<bean id="grdate" parent="student" class="com.hsp.inherit.Gradate">
<-- 如果自己配置属性name,age,则会替换从父对象继承的数据 -->
<property name="name" value="小明"/>
<property name="degree" value="学士"/>
</bean>
2.3.3.3 通过构造器注入属性
通过元素的子元素注入属性
<bean id="test" class ="...Test">
<constructor-arg index="0" type="java.lang.String" value="朱洁" />
<constructor-arg index="1" type="int" value="20"/>
<constructor-arg index="2" type="double" value="34.5" />
</bean>
2.3.3.4 分散配置
通过在ApplicationContext.xml文件中配置context:property-placeholder 引入属性文件,有多个需要使用’,'号间隔.
步骤如下:
- 配置属性文件db.property
name=scott
drivername=oracle:jdbc:driver:OracleDirver
url=jdbc:oracle:thin:@127.0.0.1:1521:hsp
pwd=tiger
-
在ApplicationContext.xml文件中引入db.properties文件,两种方式
第一种
第二种
<bean id="dbPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>xx/yy/db.properties</value>
<value>xx/yy/db2.properties</value>
</list>
</property>
</bean>
- 在ApplicationContext.xml文件中配置bean,采用占位符$方式
<bean id="dbutil" class="com.hsp.dispatch.DBUtil">
<property name="name" value="${name}" />
<property name="drivername" value="${drivername}" />
<property name="url" value="${url}" />
<property name="pwd" value="${pwd}" />
</bean>
2.3.3.5 自动装配
- 通过autowire属性装配
<bean id="foo" class="...Foo" autowire="autowire
type">
有四种自动装配类型:
- byName寻找和属性名相同的bean,若找不到,则装不上。(属性名和bean id名必须相同)
- byType:寻找和属性类型相同的bean,找不到,装不上,找到多个抛异常。
- constructor:查找和bean的构造参数一致的一个或多个bean,若找不到或找到多个,抛异常。按照参数的类型装配
- autodetect: (3)和(2)之间选一个方式。不确定性的处理与(3)和(2)一致。
- defualt : 这个需要在
- no : 不自动装配,这是autowrite的默认值。
老板:不懂spring还来做项目?建议离职一、Spring框架二、装配Bean default说明
需要在
- 如果在指定了default-atuowrite后,所有的bean的默认的autowire就是中指定的装配方法;
- 如果没有在指定defualt-autorwire,则默认是defualt-autorwire=”no”,所有的bean则默认不自动装配,除非自己配置autowire
篇幅有限,暂时更新到这里啦!下一篇尽快上传~
看到这里的小伙伴,如果你喜欢这篇文章的话,别忘了转发、收藏、留言互动!
最近我新整理了一些Java资料,包含面经分享、模拟试题、和视频干货,如果你需要的话,欢迎私信我!
如果对文章有任何问题,欢迎在留言区和我交流~
还有,关注我!关注我!关注我!