spring的概況:spring是一個(gè)開源框架娇跟,為了解決企業(yè)應(yīng)用開發(fā)的復(fù)雜性而創(chuàng)建的,但現(xiàn)在不止用于企業(yè)應(yīng)用
spring事業(yè)一個(gè)輕量級(jí)的ioc(控住反轉(zhuǎn))和aop面向切面 的容器框架虫碉。
1:從大小和開銷兩方面而言Spring都是輕量級(jí)的
2:通過控制反轉(zhuǎn)(ioc)技術(shù)達(dá)到松耦合的目的
3:提供面向切面的編程的豐富支持,允許通過分離應(yīng)用的業(yè)務(wù)邏輯于系統(tǒng)級(jí)服務(wù)進(jìn)行內(nèi)聚性的開發(fā)區(qū)
4:包含并管理應(yīng)用對(duì)象的配置和生命周期胸梆,這個(gè)意義上是一個(gè)容器
5:將簡(jiǎn)單的組件配置 敦捧,組合成復(fù)雜的應(yīng)用,這個(gè)意義上是框架碰镜。
spring的結(jié)構(gòu)圖:
spring的作用 :
1: 容器
2:提供對(duì)多種技術(shù)的支持(jms mq UnitTest兢卵。。绪颖。秽荤。。柠横。)
3:Aop(事務(wù)管理窃款,日志)
4:提供眾多的方便應(yīng)用的輔助類(JDBC Template)
5:對(duì)主流框架良好的支持(hihibernate等)
spring的適用范圍
1:構(gòu)建企業(yè)級(jí)應(yīng)用(ssm,ssh)
2:?jiǎn)为?dú)使用bean容器(bean的管理)
3:?jiǎn)为?dú)使用Aop進(jìn)行切面管理
4:其他Spring的功能(如對(duì)消息的支持)
5:在互聯(lián)網(wǎng)中的應(yīng)用牍氛。
什么是框架
特點(diǎn):1半成品
2封裝了特定的處理流程和控制邏輯
3成熟的晨继,不斷升級(jí)改進(jìn)的軟件
框架和類庫的區(qū)別
1框架一般封裝了邏輯,高內(nèi)聚的搬俊,類庫則是松散的工具組合紊扬。
2框架專注于某一領(lǐng)域,類庫更加的通用唉擂。
接口
1用于溝通中介物的抽象化
2實(shí)體把自己提供給外界的一種抽象化說明餐屎,用以由內(nèi)部操作分離出外部溝通的方法,使其能夠被修改內(nèi)部而不影響外界其他的實(shí)體與之與其交互的方式
3對(duì)應(yīng)java接口及聲明玩祟,聲明了哪些方法對(duì)外提供.
4在java8中接口擁有方法體
面向接口編程
1結(jié)構(gòu)設(shè)計(jì)中腹缩,分清層次及調(diào)用關(guān)系。每層只向外(上層)提供一組功能的接口卵凑,各層間依賴接口并非實(shí)現(xiàn)類
2:接口實(shí)現(xiàn)變動(dòng)不影響各層間的調(diào)用庆聘,這一點(diǎn)在公共服務(wù)中尤為的重要 。
3:面向接口編程中的接口是用于隱藏具體實(shí)現(xiàn)和實(shí)現(xiàn)多態(tài)性的組件
例子:
public interface OneInterface{
String hello(String word);
}
public class OneInterfaceImpl implements OneInterface{
@Overiide
public String hello(String word){
return "OneInterface"+word;
}
public static void main(String[] args){
OneInterfaceImpl one=new OneInterfaceImpl();
System.out.println(one.hello("word"));
}
}
什么是ioc:
控制反轉(zhuǎn)勺卢,控制權(quán)的轉(zhuǎn)移,應(yīng)用程序本身不負(fù)責(zé)依賴對(duì)象的創(chuàng)建和維護(hù)象对,而是由外部容器負(fù)責(zé)依賴和維護(hù)的
Di(依賴注入)是一種實(shí)現(xiàn)方式
目的:創(chuàng)建對(duì)象并組裝對(duì)象之間的關(guān)系
image.png
(獲得依賴對(duì)象的過程被反轉(zhuǎn)了黑忱,這個(gè)過程由自身管理變成了由Ioc容器主動(dòng)注入)
spring中bean的配置(兩種方式1配置 2注解)、
1:配置方式
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
>
//命名空間
<bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
//聲明一個(gè)bean ,id為唯一標(biāo)識(shí)甫煞,class對(duì)于具體的類
</bean>
</beans>
單元測(cè)試
1:下載junit并引入jar包
2:創(chuàng)建UnitTestBean類菇曲,完成對(duì)Spring配置文件的加載,銷毀
3:所有單元測(cè)試類都要繼承自UnitTestBean類抚吠,通過他的getBean方法獲取想要得到的對(duì)象
4:子類(具體執(zhí)行單元測(cè)試的類)加注解:
@RunWith(BlockJUnit4ClassRunner.class)
5:單元測(cè)試的方法加注解:@Test
6:右鍵選擇要執(zhí)行的單元測(cè)試方法執(zhí)行或執(zhí)行一個(gè)類全部的單元測(cè)試方法常潮。
具體的代碼:
public class UnitTestBase {
private ClassPathXmlApplicationContext context;
private String springXmlpath;
public UnitTestBase() {}
public UnitTestBase(String springXmlpath) {
this.springXmlpath = springXmlpath;
}
@Before
public void before() {
if (StringUtils.isEmpty(springXmlpath)) {
springXmlpath = "classpath*:spring-*.xml";
}
try {
context = new ClassPathXmlApplicationContext(springXmlpath.split("[,\\s]+"));
context.start();
} catch (BeansException e) {
e.printStackTrace();
}
}
@After
public void after() {
context.destroy();
}
@SuppressWarnings("unchecked")
protected <T extends Object> T getBean(String beanId) {
try {
return (T)context.getBean(beanId);
} catch (BeansException e) {
e.printStackTrace();
return null;
}
}
protected <T extends Object> T getBean(Class<T> clazz) {
try {
return context.getBean(clazz);
} catch (BeansException e) {
e.printStackTrace();
return null;
}
}
}
測(cè)試類:
@RunWith(BlockJUnit4ClassRunner.class)
public class TestOneInterface extends UnitTestBase {
public TestOneInterface() {
super("classpath:spring-ioc.xml");
}
@Test
public void testSay() {
OneInterface oneInterface = super.getBean("oneInterface");
oneInterface.say("This is a test.");
}
}
bean容器的初始化過程
基礎(chǔ)兩個(gè)包
-org.springframework.beans
-org.springframework.context
-BeanFactory提供配置結(jié)構(gòu)和基本功能,加載并初始化Bean
-ApplicationContext保存了Bean對(duì)象并在spring中被廣泛的使用
加載方式-ApplicationContext
-本地文件
-Classpath
-Web應(yīng)用中依賴servlet或Listener
案例:
1文件:
FileSystemXmlApplicationContext context=new FileSystemXmlApplicationContext("F:/Spring/src/main/resources/spring-ioc.xml");
2classpath:
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("classpath:spring-ioc.xml");
3web應(yīng)用
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--2 -->
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextloaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
//有兩個(gè)類分別為ContextLoaderListener和ContextloaderServlet楷力,都可以加載配置文件喊式。
spring的注入
spring注入是指在啟動(dòng)spring容器加載bean配置的時(shí)候,完成對(duì)變量的賦值
常用的兩種方式
1:設(shè)置注入
2:構(gòu)造注入
設(shè)置注入
<bean id="DAO" class="com.atguigu.crud.bean.InjectionDAO">
</bean>
<bean id="ServiceImpl " class="com.atguigu.crud.bean.InjectionServiceImpl ">
<property name="injectionDAO" ref="DAO"/>
</bean>
設(shè)置注入會(huì)提前調(diào)用屬性的set的方法萧朝,為屬性賦值岔留。
構(gòu)造注入
<bean id="DAO" class="com.atguigu.crud.bean.InjectionDAO">
</bean>
<bean id="ServiceImpl " class="com.atguigu.crud.bean.InjectionServiceImpl ">
<constructor-arg name="injectionDAO" ref="DAO"/>
</bean>
通過調(diào)用構(gòu)造方法進(jìn)行賦值
代碼:
public class InjectionServiceImpl implements InjectionService {
private InjectionDAO injectionDAO;
//構(gòu)造器注入
public InjectionServiceImpl(InjectionDAO injectionDAO1) {
this.injectionDAO = injectionDAO1;
}
//設(shè)值注入
public void setInjectionDAO(InjectionDAO injectionDAO) {
this.injectionDAO = injectionDAO;
}
}
bean的配置項(xiàng)
1:id (唯一標(biāo)識(shí) )
2:Class(具體類,這個(gè)是必須的)
3:Scope(作用域)
4:Constructor argguments(構(gòu)造器倉鼠)
5:Properties(屬性)
6:Autowiring mode(自動(dòng)裝配模式)
7:lazy-initialization mode(懶加載模式)
8:Initalization/destruction method(初始化和銷毀的方法)
bean的作用域Scope(五種類型)
1:singleton:?jiǎn)卫旒恚敢粋€(gè)bean容器中只存在一份
2:prototype:每次請(qǐng)求(每次使用)創(chuàng)建新的實(shí)列献联,destroy方式不生效
3:request:每次http請(qǐng)求創(chuàng)建一個(gè)實(shí)列且僅在當(dāng)前的request內(nèi)有效
4:session:同上每次http請(qǐng)求創(chuàng)建,當(dāng)前session內(nèi)有效
5:global session:基于portlet的web中有效(portlet定義了global session)何址,如果在web中里逆,同session
(如果在單元測(cè)試類中用兩個(gè)測(cè)試方法獲取同一個(gè)id的bean,
會(huì)先啟動(dòng)一個(gè)ioc容器用爪,關(guān)閉后在啟動(dòng)一個(gè)原押,因此如果使用Scope為單例將獲得兩個(gè)不同的bean如下圖:)
bean的生命周期
bean的初始化:(兩種)
1:實(shí)現(xiàn)org.springframework.beans.factory.InitializingBean接口,覆蓋afterPropertiesSet方法
image.png
2:配置Init-method
image.png
bean的銷毀:(兩種)
1實(shí)現(xiàn)org.springframework.beans.factory.DisposableBean接口项钮,覆蓋destroy方法
image.png
2:配置Destroy-method
image.png
配置全局默認(rèn)初始化班眯,銷毀方法(可選,沒有方法的話烁巫,不會(huì)報(bào)異常署隘,上面兩種必須配置方法)
<?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"
default-init-method="defautInit" default-destroy-method="defaultDestroy">
<bean id="beanLifeCycle" class="com.imooc.lifecycle.BeanLifeCycle" init-method="start" destroy-method="stop"></bean>
</beans>
同時(shí)以兩種方式創(chuàng)建和初始化bean的時(shí)候?qū)崿F(xiàn)接口優(yōu)先于配置,當(dāng)配置了初始化或銷毀方法亚隙,全局默認(rèn)將被覆蓋
Aware
1:Spring中提供了一些以Aware結(jié)尾的接口磁餐,實(shí)現(xiàn)了Aware接口的bean在被初始化之后,可以獲得相應(yīng)的資源
2:通過Aware接口阿弃,可以對(duì)Spring相應(yīng)的資源進(jìn)行操作(一定要慎重)
3:對(duì)Spring進(jìn)行簡(jiǎn)單的擴(kuò)展提供了方便的入口
1 ApplicationContextAware:獲取ApplicationContext(上下文路徑對(duì)象)
2 ApplicationEventPublisherAware
3 BeanClassLoaderAware
4 BeanFactoryAware
5 BeanNameAware:獲取BeanName
6 BootstrapContextAware
7 LoadTimeWeaverAware
等等诊霹。
bean的自動(dòng)裝配
1:no:不做任何的操作
2:byname: 根據(jù)屬性名自動(dòng)裝配磨取。此選項(xiàng)將檢查容器并根據(jù)查找與屬性完全一致的bean赂摆,并將其與屬性自動(dòng)裝配
3:bytype:如果容器中存在一個(gè)與指定屬性相同的bean劲弦,那么將與該屬性自動(dòng)裝配茁彭;如果存在多個(gè)該類型的bean甥雕,那么將會(huì)拋出異常贬堵,并指出不能使用bytype的方式進(jìn)行自動(dòng)裝配招驴;如果沒有找到相應(yīng)的bean腹鹉,則什么事情都不會(huì)發(fā)生
4:Constructor:于bytype的方式類似,不同之處在于它用于構(gòu)造參數(shù)怔蚌。如果容器沒有找到與構(gòu)造參數(shù)類型一致的bean巩步,那么將會(huì)拋出異常。
<?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"
default-autowire="constructor"http://bytype//byname>
<bean id="autoWiringService" class="com.imooc.autowiring.AutoWiringService" ></bean>
<bean class="com.imooc.autowiring.AutoWiringDAO" ></bean>
</beans>
以byname和bytype的方式自動(dòng)裝配的話桦踊,被引用的類椅野,聲明set方法(尋找和id名一樣的bean,bytype和bean的id名無關(guān))
以bytype的方式自動(dòng)裝配的話籍胯,被引用的類竟闪,聲明構(gòu)造方法
public class AutoWiringService {
private AutoWiringDAO autoWiringDAO;
//Constructor設(shè)置構(gòu)造函數(shù)
public AutoWiringService(AutoWiringDAO autoWiringDAO) {
System.out.println("AutoWiringService");
this.autoWiringDAO = autoWiringDAO;
}
//byname設(shè)置set方法
public void setAutoWiringDAO(AutoWiringDAO autoWiringDAO) {
System.out.println("setAutoWiringDAO");
this.autoWiringDAO = autoWiringDAO;
}
public void say(String word) {
this.autoWiringDAO.say(word);
}
}
文件獲取之Resource
針對(duì)于資源文件的統(tǒng)一接口
Resource:
1UrlResource:Url對(duì)應(yīng)的資源,根據(jù)一個(gè)Url地址即可構(gòu)建
2ClassPathResource:獲取類路徑文件下的資源文件
3FileSystemResource:獲取文件系統(tǒng)里面的資源文件
4ServletContextResource:ServletContext封裝的資源芒炼,用于訪問ServletContext環(huán)境下的資源
5InputStreamResource:針對(duì)于輸入流封裝的資源
6ByteArrayResource:針對(duì)于字節(jié)數(shù)組封裝的資源
ResourceLoader(對(duì)Resource進(jìn)行資源加載)
spring中所有的application Context都實(shí)現(xiàn)了ResourceLoader接口
輸入的路徑類型如下圖:
代碼如下:
public class MoocResource implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
public void resource() throws IOException {
Resource resource = applicationContext.getResource("config.txt"http://寫路徑瘫怜,沒有前綴的時(shí)候根據(jù)classpath來創(chuàng)建的);
System.out.println(resource.getFilename());
System.out.println(resource.contentLength());
}
}
==================================================================================
方式二注解基于注解方式的ioc容器的管理
從spring3.0開始,spring javaConfig項(xiàng)目提供了很多的特征本刽,包括使用java而不是xml來定義bean鲸湃。
@Component是一個(gè)通用的注解,可以用于任何的bean
@Repository通常用于注解dao類子寓,即持久層
@Service通常用于注解Service類暗挑,即服務(wù)層
@Controller通常用于注解Controller類,即控制層(mvc)
image.png
類的自動(dòng)檢測(cè)和注冊(cè)bean
標(biāo)簽component-scan會(huì)掃描基于類和方法的注解
標(biāo)簽annotation-config只會(huì)去掃描類中方法和屬性的注解(前者包含后者)
type的類型有:
annotation 目標(biāo)組件中出現(xiàn)在type級(jí)別的注釋斜友。
assignable 目標(biāo)組件可分配給(擴(kuò)展/實(shí)現(xiàn))的類(或接口)(具體的某一個(gè)類)炸裆。
aspectj 由目標(biāo)組件匹配的AspectJ類型表達(dá)式。
regex 由目標(biāo)組件類名匹配的正則表達(dá)式鲜屏。
custom :org.springframe .core的自定義實(shí)現(xiàn)烹看。TypeFilter接口類型。
沒有指定名稱(bean的name屬性)的話洛史,默認(rèn)id為類名首字母小寫
自定義命名策略需要指定name-genregenerator為我們需要實(shí)現(xiàn)接口的類
@Required注解(不常用惯殊,了解即可)
1:@Required適用bean屬性的set方法
2:這個(gè)注解表示,受影響的bean屬性必須在配置的時(shí)候被填充也殖,通過在bean定義或通過自動(dòng)裝配一個(gè)明確的屬性值
image.png
@Autowired
1可以將 @Autowired注解在set方法上
2@Autowired可以用于構(gòu)造器或者成員變量
默認(rèn)情況下土思,如果找不到合適的bean將會(huì)導(dǎo)致@Autowired失敗拋出異常,可以通過下面的方式來避免(非必須的忆嗜,只有在使用的時(shí)候發(fā)現(xiàn)異常)
注意點(diǎn):
1每個(gè)類只能有一個(gè)構(gòu)造器被標(biāo)記為Required=true(默認(rèn)值為false)
2@Autowired的必要屬性己儒,建議使用@Required來代替
例子:
public interface BeanInterface {
}
@Order(1)
@Component
public class BeanImplTwo implements BeanInterface {
}
@Order(2)
@Component
public class BeanImplOne implements BeanInterface {
}
測(cè)試類
@Component
public class BeanInvoker {
@Autowired
private List<BeanInterface> list;
@Autowired
private Map<String, BeanInterface> map;
@Autowired
@Qualifier("beanImplTwo")
private BeanInterface beanInterface;
public void say() {
if (null != list && 0 != list.size()) {
System.out.println("list...");
for (BeanInterface bean : list) {
System.out.println(bean.getClass().getName());
}
} else {
System.out.println("List<BeanInterface> list is null !!!!!!!!!!");
}
System.out.println();
if (null != map && 0 != map.size()) {
System.out.println("map...");
for (Map.Entry<String, BeanInterface> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue().getClass().getName());
}
} else {
System.out.println("Map<String, BeanInterface> map is null !!!!!!!!!!");
}
System.out.println();
if (null != beanInterface) {
System.out.println(beanInterface.getClass().getName());
} else {
System.out.println("beanInterface is null...");
}
}
輸出結(jié)果
@Order只針對(duì)list有效,map無效
xml中定義@qualifier
自定義@qualifier
1:
2:
基于java容器的注解@bean
(@Component和@Bean都是用來注冊(cè)Bean并裝配到Spring容器中捆毫,但是Bean比Component的自定義性更強(qiáng)闪湾。可以實(shí)現(xiàn)一些Component實(shí)現(xiàn)不了的自定義加載類绩卤。)
如果定義在方法上@bean的名稱沒有指定名稱(默認(rèn)為方法名)
使用@ImportResource和@Value注解進(jìn)行資源文件的讀取
xml加載資源文件
注解加載資源文件:
@Bean和@Scope
proxyMode代理方式
基于泛型的自動(dòng)裝配
自定義注解(了解)
注解@Resource(jsr-250支持)
(方法名和屬性名 )
回調(diào)初始化和銷毀
例子:
@Repository
public class JsrDAO {
public void save() {
System.out.println("JsrDAO invoked.");
}
}
//@Service
@Named
public class JsrServie {
// @Resource
// @Inject
private JsrDAO jsrDAO;
// @Resource
@Inject
public void setJsrDAO(@Named("jsrDAO") JsrDAO jsrDAO) {
this.jsrDAO = jsrDAO;
}
@PostConstruct
public void init() {
System.out.println("JsrServie init.");
}
@PreDestroy
public void destroy() {
System.out.println("JsrServie destroy.");
}
public void save() {
jsrDAO.save();
}
}
執(zhí)行結(jié)果:
@Autowired和@Resource區(qū)別:
1响谓、 @Autowired與@Resource都可以用來裝配bean. 都可以寫在字段上,或?qū)懺趕etter方法上损合。
2省艳、 @Autowired默認(rèn)按類型裝配(這個(gè)注解是屬業(yè)spring的)娘纷,默認(rèn)情況下必須要求依賴對(duì)象必須存在,如果要允許null值跋炕,可以設(shè)置它的required屬性為false赖晶,如:@Autowired(required=false) ,如果我們想使用名稱裝配可以結(jié)合@Qualifier注解進(jìn)行使用辐烂,如下:
@Autowired()@Qualifier("baseDao")
privateBaseDao baseDao;
3遏插、@Resource(這個(gè)注解屬于J2EE的),默認(rèn)按照名稱進(jìn)行裝配纠修,名稱可以通過name屬性進(jìn)行指定胳嘲,如果沒有指定name屬性,當(dāng)注解寫在字段上時(shí)扣草,默認(rèn)取字段名進(jìn)行安裝名稱查找了牛,如果注解寫在setter方法上默認(rèn)取屬性名進(jìn)行裝配。當(dāng)找不到與名稱匹配的bean時(shí)才按照類型進(jìn)行裝配辰妙。但是需要注意的是鹰祸,如果name屬性一旦指定,就只會(huì)按照名稱進(jìn)行裝配密浑。
@Resource(name="baseDao")
privateBaseDao baseDao;
總結(jié):
@Autowired//默認(rèn)按type注入
@Qualifier("cusInfoService")//一般作為@Autowired()的修飾用
@Resource(name="cusInfoService")//默認(rèn)按name注入蛙婴,可以通過name和type屬性進(jìn)行選擇性注入
一般@Autowired和@Qualifier一起用,@Resource單獨(dú)用尔破。
當(dāng)然沒有沖突的話@Autowired也可以單獨(dú)用
@Inject注解
3引入jar包
注解在類上于@Component等效
總結(jié)來源于慕課網(wǎng)免費(fèi)課程《spring入門篇》街图。