一篇文章入門Spring框架

Spring是個容器,可以用來管理bean對象

如果沒有使用Spring,我們要使用對象時需要自己手動new 一個對象出來
獲取對象之前需要配置Spring(ApplicationContext.xml):

<!---->

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">
	
	<!--在spring配置中加入bean配置 class爲類路徑-->
	<bean name="user" class="com.echo.bean.User"></bean>
	
</beans>

然後在代碼加載配置文件,向spring申請一個User對象:


ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("ApplicationContext.xml");
User bean = (User)ac.getBean("user");//根據id獲取User對象,每次獲取的對象都是同一個

那麼如何給配置在xml文件裏對象賦值?可以使用依賴注入(就是在xml文件裏事先配置好屬性地值):

<bean name="user" class="com.echo.bean.User">
	<property name="u_id" value="5"></property>
</bean>

web項目中地依賴關係:
在這裏插入圖片描述

Spring-Ioc | DI 概念:(要實現IOC依賴DI的支持 )

IoC:反轉控制
反轉:將我們自己創建對象的工作交給Spring容器幫我們完成
控制:就是有Spring幫我們負責創建銷燬對象,掌控對象的生命週期,我們在需要使用對象的時候跟Spring申請即可
IOC是一種編程思想,也是一種新的設計模式,它將幫助我們管理對象,它需要DI(依賴注入)技術的支持,維護依賴關係

DI:依賴注入
將值通過配置的方式爲變量初始化 / 賦值(注入)

Spring配置:

xml配置:
bean元素:交由Spring管理的對象都要配置在bean標籤中
Bean的創建的方式:無參構造(常用)、靜態工廠、動態工廠,默認使用無參構造方法構造,如果沒有無參構造器,會報錯

bean標籤屬性:
lazy-init(懶加載):
在ClassPathXmlApplicationContext對象創建時,容器中的所有對象都會被自動創建
如果配置大量的bean,會導致內存過大
Spring推出了延遲加載解決這一問題(懶加載):

<!---->
<!--就是直到要使用時才加載-->
	<bean name="user" class="com.echo.bean.User" lazy-init="true">
		<property name="u_id" value="5"></property>
	</bean>

scope:
singleton(常用):單例模式(默認)
prototype(特殊時使用):多例模式(每次申請都新構造一個新的對象,如果使用該屬性值,創建的對象就會交給程序員管理,不再由Spring管理)
request(不常用):在web環境下,如果scope屬性爲request,那麼這個對象被創造出來時。它的生命週期會與request一致
session(不常用):同理,生命週期與session一致

初始化方法Init-method和銷燬方法destroy-method
Init-method:如果對象需要在創建後調用一些初始化方法(非構造器),可以使用這個屬性設置
destroy-method:如果對象在銷燬前需要調用一些方法(例如釋放資源),可以使用這個屬性設置,該方法在容器關閉後激活(單例模式有效)

Spring屬性注入:(在xml中配置屬性)

Setter方法注入:如果要注入屬性,則類中必須要有屬性對應的Setter方法
引用類型(自定義類型):如果對象中包含另一個對象的引用(自定義類型),則需要再同級標籤下再配置一個該類型的bean,然後在主對象中使用ref關聯起來:

<bean name="user" class="com.echo.bean.User">
	<property name="u_id" value="5"></property>
	<property name="u_username" value="echo"></property>
	<property name="pet" ref="pet"></property>
</bean>
	
<bean name="pet" class="com.echo.bean.Pet">
	<property name="name" value="mypet"></property>
</bean>

構造方法注入:利用帶參構造器注入
無參構造器是必須提供的,spring用無參構造器創建對象
構造方法注入只是將屬性注入

<!--要把構造器所有的參數都配置上-->
<bean name="userplus" class="com.echo.bean.User">
	<constructor-arg name="u_username" value="abc" type="java.lang.String"></constructor-arg>
	<constructor-arg name="u_password" value="abc" type="java.lang.String"></constructor-arg>
</bean>

複雜類型注入(Array、List、Set、Map、Properties):
示例:被注入的java類:

public class Col {
//以下getter、setter省略
	private Object[] array;
	private ArrayList list;
	private Map map;
	private Properties properties;
	private Set set;
}

bean注入配置

<!---->
<!--數組使用array,列表使用list,鍵值對使用map\props-->
	<bean name="col" class="com.echo.bean.Col">
		<property name="array">
			<array>
				<!--內容使用value標籤包圍-->
				<value>123</value>
				<value>abc</value>
				<!--可以指定內容爲引用類型-->
				<ref bean="pet" />
			</array>
		</property>
		<property name="list">
			<list>
				<value>listtiem1</value>
				<value>listtiem2</value>

			</list>
		</property>

		<property name="set">
			<set>
				<value>setitem1</value>
				<value>setitem2</value>

			</set>
		</property>

		<property name="map">
			<map>
				<!--map內容使用entry包圍,在其中設置key和value-->
				<entry key="A" value="a"></entry>
				<entry key="B" value="b"></entry>
				<!--同樣可以設置引用類型的key和value-->
				<entry key-ref="user" value-ref="pet"></entry>
			</map>
		</property>

		<property name="properties">
			<props>
				<!--prop的value直接寫在標籤裏-->
				<prop key="name">root</prop>
				<prop key="password">123456789</prop>
			</props>
		</property>
	</bean>
Spring註解配置:

可以使用註解配置將對象交給Spring管理,首先要打開基本掃描:

<!-- 開啓組件掃描 base-package掃描該包下以及子包的所有註解-->
<context:component-scan base-package="com.echo.bean"></context:component-scan>
	

打開這個Spring就會自動掃描包下的所有註解
Spring註解:
@Component():
在類定義的頂上加入該註解,則會將該類的實例交給Spring管理,例如:

@Component("user2")
public class User2 {
...
}

Spring爲了區分對象在不同層的註解使用了以下注釋:

//功能和@Component("user2")一樣,只是名稱不同,有利於區分
@Controller("user2") //對應web層
@Service("user2")	//對應service層
@Repository("user2")	//對應Dao層

@Scope:
使用方式:
將值賦值給scopeName,也可以省略scopeName

@Scope(scopeName = "prototype")
public class User2 {
...
}

@PostConstruct:
在構造器調用後調用

@PreDestroy:
在對象銷燬前調用

Spring註解注入:

@Value():
注入基本數據,可以給成員變量註解,也可以給方法註解,如果成員變量私有,推薦在setter方法上使用該註解。

@Resource和@Autowired:
以上兩種註解用來輸入引用數據,作用是可以消除代碼中的setter和getter,還有bean中的properties屬性
@Autowired:
自動裝配,如果設置該註解,Spring會自動在管理的類中按照查找同類型的實例,並填裝上,如果找到多個或沒有找到,就報錯。

@Resource:
功能同上,需要設置name,用來指定填裝的實例,而不是自動查找,比Autowired推薦使用。

Spring集成的JUnit測試:
@RunWith(SpringJUnit4ClassRunner.class)//使用junit進行測試,幫我們創建容器
@ContextConfiguration("classpath:ApplicationContext.xml")
public class SpringJunit {

	//可以直接從容器中獲取對象
	@Resource(name = "user")
	private User user;
	
	@Test
	public void test() {
		System.out.println(user);
	}
	
	
}
Spring分包配置:

如果有多個配置文件
可以通過import將某個配置文件添加到其他配置文件中

<!--導入其他配置文件-->
<import resource="ApplicationContext.xml"/>
配置Spring隨項目啓動:

在web.xml中加入監聽器配置:

<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:ApplicationContext.xml</param-value>
</context-param>

然後可以在java中調用容器:

WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
Spring-aop中的一些名詞:

JoinPoint: 連接點。目標對象中,那些方法會被攔截
Pointcut: 切入點。篩選連接點,最終要增強的方法
Advice: 通知/增強。增強代碼
Introduction: 介入。和增強類似(執行期動態加入)
Aspect: 切面。通知 + 增強
target: 目標。被代理對象
weaving: 織入。把切面的代碼應用到目標對象來創建新的代理對象
proxy: 代理。把切面的代碼引用到目標對象來創建新的代理對象

Spring-aop自定義通知類型:

before 前置通知
after 最終通知(後置通知)
afterReturning 成功通知(後置通知)
afterThrowing 異常通知(後置通知)
around 環繞通知

使用配置使用上述通知:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">

	<!-- 目標對象,需要增強/代理的對象 -->
	<bean name="userService"
		class="com.echo.testservice.UserServiceImpl"></bean>

	<!-- 通知對象,裏面包含通知/增強的方法 -->
	<bean name="myAdvice" class="com.echo.aop.MyAdvice"></bean>


	<aop:config>
		<!-- 切入點 expression:切入點表達式,可以配置要增強的方法,id是唯一標識
		不能有參數
		* com.echo.testservice.UserServiceImpl.*(..)
		* 標識全匹配,..表示任何參數
		-->
		<aop:pointcut expression="execution(* com.echo.testservice.UserServiceImpl.*(..))" id="servicePc" />

		<!-- 切面 通知+切入點 -->
		<aop:aspect ref="myAdvice">
			<aop:before method="before" pointcut-ref="servicePc"/>
			
			<!-- 最終註釋 後置通知-->
			<aop:after method="after" pointcut-ref="servicePc"/>
			
			<!-- 成功通知 後置通知 -->
			<aop:after-returning method="afterReturning" pointcut-ref="servicePc"/>
			
			<!-- 異常通知 後置通知 -->
			<aop:after-throwing method="afterThrowing" pointcut-ref="servicePc"/>
			
			<!-- 環繞通知  -->
			<aop:around method="around" pointcut-ref="servicePc"/>
		</aop:aspect>
	</aop:config>
</beans>
配置Spring-aop事務示例:

配置事務核心管理器:

<!---->
<!-- 配置事務核心管理器:配置事務核心管理器,首先要先配置數據庫實例 -->
<!--c3p0-->
<bean name="dataSource"
	class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
	<property name="jdbcUrl"
		value="jdbc:mysql://localhost:3306/spring"></property>
	<property name="user" value="root"></property>
	<property name="password" value="123456789"></property>
</bean>

<!--然後將數據庫實例注入管理器-->
<bean name="transactionManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property>
</bean>

配置事務通知:

<!---->
<!-- 事務通知 -->


<tx:advice id="txAdvice"

	transaction-manager="transactionManager"><!--爲事務配置事務管理器-->
	
	<tx:attributes><!--配置事務的相關屬性-->
	<!--在attributes中配置事務相關的操作數據庫的方法:
	
	name:需要配置事務的含有Sql操作的方法名稱
	isolation:隔離級別
	propagation:Spring特有的事務傳播,一般可以使用默認的REQUIRED
	read-only:是否只讀,如果有需要寫入數據庫,爲false
	
	-->
		<tx:method name="transferAccounts" isolation="DEFAULT"
			propagation="REQUIRED" read-only="false" />
	</tx:attributes>
</tx:advice>
<!--此時事務沒有綁定切入點-->

配置aop:

<!-- 配置aop:綁定切入點 -->
<aop:config>
	<!-- 配置切入點 -->
	<aop:pointcut
		expression="execution(* com.echo.service.AccountServiceImpl.*(..))"
		id="txPc" />
	
		<!--配置爲創建好的通知器關聯切入點-->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/>
</aop:config>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章