HTB-靶機-Shocker
maven倉庫地址:https://mvnrepository.com/search?q=spring
bean裝配方式的選擇:優先自動裝配、然後用基於javaConfig的裝配、最後xml配置
1. ioc容器 基於xml裝配
ioc:inversionofcontrol,控制反轉。將建立物件的工作交給框架完成。
基於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"> <bean id="classA" class="com.xt.abc.impl.ClassA"></bean> </beans>
1.1 ApplicationContext應用上下文
讀取完配置檔案(或註解),預設情況下就會通過反射建立物件,並組裝物件
此介面的實現類:需要spring-context.jar
FileSystemXmlApplicationContext 從可訪問的任意磁碟路徑上載入配置檔案 ClassPathXmlApplicationContext 從類的根路徑上載入(基於XML配置) WebXmlApplicationContext 在一個Web應用的範圍內載入 AnnotationConfigApplicationContext 通過配置類載入bean
使用示例:
ApplicationContext context = new ClassPathXmlApplocationContext("xxx.xml"); ClassA classA = context.getbean(xxx.ClassA.class);
1.2bean物件
配置中定義的,而由Spring IOC 容器例項化、組裝、管理的物件
(1)屬性:
id:唯一標識,用於獲取物件
class:類全限定名,用於反射建立物件
scope:物件作用域
singleton:預設,單例
prototype:多例
request:WEB專案中,表明建立的此物件存入request域
session:WEB專案中,表明建立的此物件存入session域
global session:WEB專案中,叢集環境下的一個session中
init-method:指定例項化bean時要呼叫的方法
destroy-method:指定從容器中移除銷燬bean時要呼叫的方法
(2)作用域和生命週期
bean的scope屬性指定:
singleton:單例,預設
prototype:多例,每次獲取物件時,都建立返回一個新的物件
request:每次Http請求都會建立一個新的物件,此物件只在當前請求有效
session:同一個HTTP Session共享一個物件,不同的session獲得的是不同的物件
global-session:叢集環境下,一個session共享一個物件
生命週期:
單例:
物件建立:容器建立後,就建立物件(配置檔案載入後就建立)
物件銷燬:容器銷燬時,銷燬容器
多例:
物件建立:每次獲取物件時才建立(每次getBean("xxx")時建立)
物件銷燬:由java垃圾回收器回收
(3)容器建立bean物件的三種方式
①預設的,通過class屬性指定的類的無參構造建立
<bean id="xxx" class="com.xt.ClassA" />
如上,ClassA的例項化會通過其無參構造建立
②工廠建立
即spring容器例項化工廠,但另一個類物件通過工廠物件的某個方法建立
<bean id="instanceFactory" class="com.xt.factory.InstanceFactory" /> <bean id="classa" factory-bean="instanceFactory" factory-method="createClassA"/>
如上,獲取ClassA類物件時,通過InstanceFactory類物件的 createClassA()方法獲取
③靜態工廠
<bean id="classa" class="com.xt.factory.StaticFactory" factory-method="createClassA"/>
通過StaticFactory的靜態方法createClassA()獲取物件
1.3 依賴注入
通過IOC,物件的建立交給了Spring容器;而物件的依賴關係通過依賴注入,也由spring控制
注入的資料:①基本型別、String ②其它bean ③集合型別
注入方式:①建構函式注入②setter方法 ③註解
(1)建構函式注入
建構函式需要的引數通過 constructor-arg標籤傳入
constructor-arg標籤
name:引數在建構函式中的名稱,常用
index:指定引數在建構函式引數列表中的索引位置(從0開始)
type:指定引數在建構函式中的資料型別
value:引數的值,只能是基本型別和String型別
ref:指定引用型別引數,可為其它配置過的bean型別
例:有一個類ClassA,其物件需要通過有兩個引數(例一個Stringname、一個int age)的建構函式建立
<bean id="classa" class="com.xt.ClassA"> <constructor-arg name="name" value="xt"> </constructor-arg> <constructor-arg name="age" value="20"> </constructor-arg> </bean>
如果建構函式還需要一個引用型別引數,如Datedate
<bean id="classa" class="com.xt.ClassA"> <constructor-arg name="name" value="xt"> </constructor-arg> <constructor-arg name="age" value="20"> </constructor-arg> <constructor-arg name="date" ref="now"> </constructor-arg> </bean> <bean id="now" class="java.util.Date"> </bean>
問題:
如果建立物件時用不到這些資料了,也必須要提供注入,否則無法建立物件
(2)setter方法
物件通過無參構造建立
通過property標籤注入:
property標籤
name:引數名(setter方法set字母后面那部分)
value:值,基本聯絡和String型別
ref:其它bean
例:ClassA有三個引數,有對應的setter方法
<bean id="classa" class="com.xt.ClassA"> <property name="name" value="xt"> </property> <property name="age" value="20"> </property> <property name="date" ref="now"> </property> </bean> <bean id="now" class="java.util.Date"> </bean>
String傳遞空串和null:
<bean id="classa" class="com.xt.ClassA"> <property name="str1" value=""/> <property name="str2"><null/></property> </bean>
------
注入集合資料:陣列、List、Set、Map、Properties
通過構造或setter方式裡面的子標籤 <list>、<array>、<set> 、<map>、<entry>、<props>
例:ClassA需要這些集合型別引數
<bean id="classa" class="com.xt.ClassA"> <property name="myList"> <list> <value>A</value> <value>B</value> <value>C</value> </list> </property> <property name="myMap1"> <map> <entry key="key1" value="val1"/> <entry key="key2" value="val2"/> </map> </property> <property name="myProp"> <props> <prop key="key1">val1</prop> <prop key="key2">val2</prop> </props> </property> </bean>
2.基於java配置類顯示配置
3.隱性的bean發現機制和自動裝配
spring容器可在不使用 <constructor-arg>、<property>元素的情況下自動裝配相互協作的bean之間的關係
<bean>的autowire屬性:
no:預設,沒有自動裝配,需要顯式指定
byName:根據屬性名裝配
byType:根據資料型別裝配;如果存在多個匹配的型別,則出錯
constructor:類似byType,此型別僅適用於建構函式引數型別,若容器中沒有一個建構函式引數型別的bean,則出錯
autodetect:spring首先嚐試通過constructor使用自動裝配連線,如果不行,則嘗試通過byType
3.自動裝配
元件掃描:spring框架自動發現應用上下文中建立的bean
自動裝配:spring框架自動滿足bean之間的依賴
3.1
需要加入 spring-aop.jar
修改bean.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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> </beans>
3.2
註解:
3.2.1 用於建立物件的
註解的效果相當於<bean id="xxx" class="xxx" />
(1)@Component 表明這個類是一個元件類,告知spring為這個類建立bean
屬性:
value:指定bean的id。不指定的id預設為當前類的類名,首字母小寫
相應的配置:
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.xt.abc.impl"> </context:component-scan> </beans>
<context:component-scan>標籤:配置spring建立容器時要掃描的包
類的定義:
@Component(value = "classA") public class ClassA { private Date date; public void fun(){ System.out.println("classa test2"); } }
這個類在該標籤指定的包下,當 getBean("classA")時即可獲取ClassA類物件
(2)@Controller、@Service、@Repository
Controller一般用於表現層的註解;Service一般用在業務層;Repository用於持久層
這三個的作用和屬性和Component是一樣的
4.2用於注入資料的
註解的效果相當於 <property name="xx" ref="xxx" />
(1)@Autowired
自動按型別注入。此註解只能注入其它bean型別。當容器中有唯一的一個bean物件,其型別與變數的型別匹配,則可以成功注入。
此註解放在成員上,則可以省略setter方法
如果容器裡有多個和此變數型別匹配的bean物件,則變數名字和bean物件在容器的key(即bean的id)進行匹配,有相同的則也可以成功注入。
(2)@Qualifier
屬性: value 為指定bean的id
在自動按照型別注入的基礎上,再安裝bean的id注入。注入欄位時要配合Autowire一起使用;給方法引數注入時,可以獨立使用
(3)@Resource
屬性:name 指定bean的id
直接按bean的id注入
(4)@Value
屬性:value 指定值(可使用spring的el表示式)
注入基本型別資料和String型別
4.3 用於改變作用範圍的
相當於 <bean id="xx" class="xxx" scope="xxxxx">
(1)@Scope
屬性:value 指定範圍取值
4.4 初始化、銷燬方法
相當於<bean id="xx" class="xx" init-method="xx" destroy-method="xxx">
(1)@PostConstruct
指定初始化方法
(2)@PreDestroy
指定銷燬方法
5. 新註解
(1)@Configuration
表示這個類是一個配置類
相對應的,獲取容器中的物件之前,要使用 AnnotationApplocationContext(xxx.class) 而不是ClassPathXmlApplicationContext("xxx.xml")
@Configuration public class AppConfig{ @Bean public MyService myService1(){ return new MyServiceImpl1(); } @Bean public MyService myService2(){ return new MyServiceImpl2(); } }
等效於:
<beans> <bean id="myService1" class="com.xt.services.MyServiceImpl1" /> <bean id="myService2" class="com.xt.services.MyServiceImpl2" /> </beans>
使用:
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); MyService1 service1 = ctx.getBean(MyService1.class); MyService2 service2 = ctx.getBean(MyService2.class);
(2)@ComponentScan
通過註解指定spring建立容器時要掃描的包,相當於 xml 中的 basePackages
(3)@Bean
屬性: name 給當前方法建立的物件指定名稱,即bean的id(預設值為方法名)
方法註解,表面使用此方法建立一個物件,並且放入spring容器
(4)@PropertySource
屬性:value[] 指定properties檔案位置;在類路徑下要寫 classpath:
用於載入properties檔案中的配置
(5)@Import
從另一個配置類中載入 @Bean 定義
-----------------------------------------------------------------------------------------------------------
通過依賴注入DI:相互協作完成功能的各個元件之間鬆散耦合
AOP:各種功能分離形成可重用的元件