快速入門
Spring是一個管理Bean的容器杂数,一個輕量級框架
-
使用Spring,需要引入對應(yīng)的依賴下載地址
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <springFramework.version>5.1.5.RELEASE</springFramework.version> </properties> <dependencies> <!-- spring相關(guān) --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springFramework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${springFramework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springFramework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${springFramework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${springFramework.version}</version> </dependency> <!--日志--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j</artifactId> <version>2.10.0</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> </dependencies>
-
管理對象,必須是一個接口一個實現(xiàn)類
/** * 戰(zhàn)士 */ public interface Fighter { void show(); }
/** * 呂布瘸洛,戰(zhàn)士類的一個實現(xiàn)類 */ public class LvBu implements Fighter { public void show() { System.out.println("戰(zhàn)士呂布"); } }
IOC控制反轉(zhuǎn)/DI依賴注入
回顧歷史
之前我們創(chuàng)建對象的方式揍移,是在一個類中主動new另一個類的對象,然后再調(diào)用其方法完成功能
public class Main {
public static void main(String[] args) {
// 獲取對象 -- 以前的方式反肋,主動創(chuàng)建
Fighter f1 = new LvBu();
f1.show();
}
}
Main類掌握著Fighter類型對象的控制權(quán)(想創(chuàng)建就創(chuàng)建)那伐,這樣帶來一個缺點,當(dāng)許多模塊都需要使用Fighter類型對象時囚玫,一旦Fighter類型對象需要發(fā)生改變喧锦,需要大量的修改其他模塊的代碼才能滿足需求读规,所以抓督,Spring提出了一種新的獲取對象的方式 -- 配置
spring配置文件
spring.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-3.0.xsd">
<!--配置一個對象-->
<!--LvBu lvbu = new LvBu();-->
<bean id="lvbu" class="com.neuedu.test.LvBu"></bean>
<bean id="guanyu" class="com.neuedu.test.GuanYu"></bean>
</beans>
public class Main {
public static void main(String[] args) {
// 獲取對象 -- 以前的方式,主動創(chuàng)建
// Fighter f1 = new LvBu();
// f1.show();
// Spring的方式獲取對象束亏,需要把對象配置在xml文件中
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
Fighter lvbu = (Fighter)applicationContext.getBean("lvbu");
Fighter guanyu = (Fighter)applicationContext.getBean("guanyu");
lvbu.show(); // 戰(zhàn)士呂布
guanyu.show(); // 戰(zhàn)士關(guān)羽
}
}
使用配置的方式帶來一個好處铃在,當(dāng)Fighter類型對象需要改變的時候,我們只需要修改spring.xml
就可以了,不需要修改其他模塊定铜,便利了開發(fā)
IOC控制反轉(zhuǎn)
對于java應(yīng)用程序來說阳液,對象的控制權(quán)逆轉(zhuǎn)了,這個概念稱為IOC--控制反轉(zhuǎn)揣炕。
之間調(diào)用或創(chuàng)建對象都是交給java應(yīng)用程序來完成帘皿,現(xiàn)在交給spring來分配。
DI依賴注入
對于spring來說畸陡,配置一個對象鹰溜,相當(dāng)于對其他調(diào)用者注入了一個可調(diào)用的對象
IOC控制反轉(zhuǎn)和DI依賴注入沒有區(qū)別,只是針對參照物不同的不同說法
屬性注入
-
構(gòu)造器注入(前提:必須有有參構(gòu)造器)
<!--默認(rèn)是調(diào)用無參構(gòu)造器創(chuàng)建對象的丁恭,若沒有無參構(gòu)造器曹动,會報錯--> <bean id="guanyu" class="com.neuedu.test.GuanYu"></bean>
public class GuanYu implements Fighter { private String name; private int age; public GuanYu() {} public GuanYu(String name, int age) { this.name = name; this.age = age; } public void show() { System.out.println(name+","+age); } }
<!--利用有參構(gòu)造器進(jìn)行屬性注入--> <bean id="guanyu" class="com.neuedu.test.GuanYu"> <!--構(gòu)造器注入屬性--> <!--給對象的name屬性,賦值“關(guān)羽”--> <constructor-arg name="name" value="關(guān)羽"></constructor-arg> <!--給對象的age屬性牲览,賦值14--> <constructor-arg name="age" value="14"></constructor-arg> </bean>
復(fù)雜對象
<?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-3.0.xsd"> <bean id="guanyu" class="com.neuedu.test.GuanYu"> <constructor-arg name="name" value="關(guān)羽"></constructor-arg> <!--屬性注入如果是對象墓陈,需要用ref關(guān)聯(lián)另一個對象id--> <constructor-arg name="weapon" ref="qinglong"></constructor-arg> </bean> <!--配一個QingLong--> <bean id="qinglong" class="com.neuedu.test.QingLong"> <property name="dps" value="50"></property> </bean> </beans>
集合
-
setter注入
<bean id="guanyu" class="com.neuedu.test.GuanYu"> <!--利用set方法注入屬性--> <property name="name" value="關(guān)羽坤"></property> <property name="age" value="144"></property> </bean>
復(fù)雜對象
<?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-3.0.xsd"> <bean id="guanyu" class="com.neuedu.test.GuanYu"> <property name="name" value="關(guān)羽"></property> <!--屬性注入如果是對象,需要用ref關(guān)聯(lián)另一個對象id--> <property name="weapon" ref="qinglong"></property> </bean> <!--配一個QingLong--> <bean id="qinglong" class="com.neuedu.test.QingLong"> <property name="dps" value="50"></property> </bean> </beans>
集合
<bean id="guanyu" class="com.neuedu.test.GuanYu"> <property name="name" value="關(guān)羽"></property> <!--屬性注入如果是對象第献,需要用ref關(guān)聯(lián)另一個對象id--> <property name="weapon" ref="qinglong"></property> <!--List<String>--> <property name="boy"> <list> <value>張飛</value> <value>馬超</value> </list> </property> <!--List<Weapon>--> <property name="repository"> <list> <ref bean="qinglong"></ref> <ref bean="fang"></ref> </list> </property> <!--Map<String,String>--> <property name="horse"> <map> <entry key="坐騎1" value="赤兔"></entry> <entry key="坐騎2" value="的盧"></entry> </map> </property> <!--Map<String,Weapon>--> <property name="weaponMap"> <map> <entry key="武器1" value-ref="qinglong"></entry> <entry key="武器2" value-ref="fang"></entry> </map> </property> </bean>
- 接口注入(Spring不支持)
自動裝配(了解)
<!-- ==========================自動按名字裝配autowire=byName=========================== -->
<!-- ==========================自動按類型裝配autowire=byType=========================== -->
<bean id="qiyi" class="com.neuedu.test1.QiYi" autowire="byType"/>
<!-- 當(dāng)按照類型裝配時贡必,有多個符合條件的對象,需要指定primary="true"表明是主要的裝配對象 -->
<bean id="wuqi" class="com.neuedu.test1.FaZhang" primary="true">
<property name="name" value="大法師之杖"></property>
</bean>
<bean id="kandao" class="com.neuedu.test1.KanDao">
<property name="name" value="大法師砍刀"></property>
</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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 開啟注解 -->
<context:annotation-config />
<bean id="guanyu" class="com.neuedu.test.GuanYu"></bean>
<bean id="abc1" class="com.neuedu.test.QingLong">
<qualifier value="test1"></qualifier>
</bean>
<bean id="abc2" class="com.neuedu.test.Fang">
<qualifier value="test2"></qualifier>
</bean>
</beans>
package com.neuedu.test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class GuanYu implements Fighter {
private String name = "關(guān)羽";
@Autowired
@Qualifier("test2")// 轉(zhuǎn)配的com.neuedu.test.Fang
private Weapon weapon;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
public void show() {
System.out.println(name);
weapon.showInfo();
}
}
注解自動裝配(重要)
spring.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.neuedu.test"></context:component-scan>
<bean id="guanyu" class="com.neuedu.test.GuanYu"></bean>
</beans>
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
GuanYu guanyu = (GuanYu)applicationContext.getBean("guanyu");
guanyu.show();
}
}
@Component("test1")
public class QingLong implements Weapon {
private int dps;
public void setDps(int dps) {
this.dps = dps;
}
public int getDps() {
return dps;
}
public void showInfo() {
System.out.println("青龍偃月庸毫,攻擊力很高");
}
}
@Component("test2")
public class Fang implements Weapon {
private int dps;
public void setDps(int dps) {
this.dps = dps;
}
public int getDps() {
return dps;
}
public void showInfo() {
System.out.println("方天畫戟赊级,攻擊力很高");
}
}
@Component
public class GuanYu implements Fighter {
private String name = "關(guān)羽";
@Autowired
@Qualifier("test2")
private Weapon weapon;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
public void show() {
System.out.println(name);
weapon.showInfo();
}
}
@Component:標(biāo)記類,交給spring統(tǒng)一管理岔绸。(不同層理逊,用的)
@Autowired:注入依賴。
@Qualifier("test2"):注入依賴具體的名字盒揉。
類型 說明
@Component 通用的構(gòu)造型注解晋被,標(biāo)示該類為Spring 組件。
@Controller 標(biāo)識將該類定義為Spring MVC controller刚盈。
@Repository 標(biāo)識將該類定義為數(shù)據(jù)倉庫(例如:Dao層)羡洛。
@Service 標(biāo)識將該類定義為服務(wù)(例如:Service層)。
AOP面向切面編程
一般應(yīng)用在如性能檢測藕漱、訪問控制欲侮、事務(wù)控制、日志記錄等
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD302.tmp)切面(Aspect)
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD312.tmp)切面是切點和通知組成肋联,通知和切點共同定義了切面的全部內(nèi)容即:它是什么威蕉,在何時何處完成其功能;
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD313.tmp)連接點(Joinpoint)
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD314.tmp)連接點是在應(yīng)用執(zhí)行過程中能夠插入切面的一個點橄仍,Spring僅支持方法的連接點韧涨,即僅能在方法調(diào)用前牍戚,方法調(diào)用后,方法拋出異常時及方法調(diào)用前后插入切面代碼虑粥。
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD315.tmp)切點(Pointcut)
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD316.tmp)切點定義了在何處應(yīng)用切面如孝,AOP通過“切點”定位特定的連接點。切點相當(dāng)于查詢條件娩贷,一個切點可以匹配多個連接點第晰。
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD317.tmp)通知(Advice)
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD318.tmp)切面的工作被成為通知,定義了切面是什么及何時使用彬祖。除了描述切面要完成的工作但荤,通知還解決了何時執(zhí)行這個工作的問題,它應(yīng)該在某個方法被調(diào)用之前涧至?之后腹躁?等。
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD319.tmp)Spring切面可以應(yīng)用5種類型的通知:
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD32A.tmp)前置通知(Before)在目標(biāo)方法被調(diào)用之前調(diào)用通知功能南蓬;
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD32B.tmp)后置通知(After)在目標(biāo)方法被完成之后調(diào)用通知功能纺非,不關(guān)心方法的輸出是什么;
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD32C.tmp)環(huán)繞通知(Around advice)通知包裹了目標(biāo)方法赘方,在目標(biāo)方法調(diào)用之前和之后執(zhí)行自定義的行為烧颖;
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD32D.tmp)異常通知(After-throwing)在目標(biāo)方法拋出異常后調(diào)用通知;
![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD32E.tmp)返回通知(After-returning)在目標(biāo)方法成功執(zhí)行之后調(diào)用通知窄陡;