spring框架
-
Ioc(Inversion of Control)控制反轉(zhuǎn)唆阿,在spring中BeanFactory是Ioc容器的核心借口邑飒,負(fù)責(zé)實(shí)例化徙缴,定位熄攘,配置應(yīng)用程序中的對(duì)象以及建立這些對(duì)象間的依賴(lài)姚淆。XmlBeanFactory實(shí)現(xiàn)BeanFactory接口孕蝉,通過(guò)獲取xml配置文件數(shù)據(jù),組成應(yīng)用對(duì)象以及對(duì)象間的依賴(lài)關(guān)系腌逢。
三種注入方式:
(1)接口注入(不推薦)
(2)構(gòu)造方法注入(死的應(yīng)用)
(3)get降淮、set方式注入(常用)
(1)、 get搏讶、set的自動(dòng)安裝佳鳖,注入方式:
autowire="defualt"
autowire=“byName”
autowire="bytype"'
例如:有兩個(gè)類(lèi)需要注入:
package org.jia;
public class Order {
private String orderNum;
@SuppressWarnings("unused")
private OrderItem orderitem;
public OrderItem getOrderitem() {
return orderitem;
}
public void setOrderitem(OrderItem orderitem) {
this.orderitem = orderitem;
}
public String getOrderNum() {
return orderNum;
}
public void setOrderNum(String orderNum) {
this.orderNum = orderNum;
}
}
package org.jia;
public class OrderItem {
private String orderdec;
public String getOrderdec() {
return orderdec;
}
public void setOrderdec(String orderdec) {
this.orderdec = orderdec;
}
}
getter&&setter方式第一種注入:defualt
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="orderItem" class="org.jia.OrderItem">
<property name="orderdec" value="item00001"></property>
</bean>
<bean id="order" class="org.jia.Order" >
<!-----注入變量 名字必須與類(lèi)中的名字一樣------->
<property name="orderNum" value="order000007"></property>
<!--注入對(duì)象 名字為orderitem媒惕,所屬的類(lèi)的應(yīng)用id為orderItem-->
<property name="orderitem" ref="orderItem"></property>
--></bean>
</beans>
getter&&setter方式第二種注入:byName
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--此時(shí)的id就必須與Order.java中所定義的OrderItem的對(duì)象名稱(chēng)一樣了系吩,不然就會(huì)找不到-->
<bean id="orderitem" class="org.jia.OrderItem">
<property name="orderdec" value="item00001"></property>
</bean>
<bean id="order" class="org.jia.Order" autowire="byName">
<property name="orderNum" value="order000007"></property>
</bean>
</beans>
getter&&setter方式第三種注入:byType
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--按照byType注入則就與id沒(méi)有關(guān)系,可以隨便定義id 6饰怠J缑怠!但是不能出現(xiàn)多個(gè)此類(lèi)的id-->
<bean id="orderitdfadafaem" class="org.jia.OrderItem">
<property name="orderdec" value="item00001"></property>
</bean>
<bean id="order" class="org.jia.Order" autowire="byType">
<property name="orderNum" value="order000007"></property>
</bean>
</beans>
(2)面睛、關(guān)于構(gòu)造器的注入:
autowire="constructor"
orderitem = item;
}```
需要在Order.java中加入一個(gè)構(gòu)造器
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="orderItem" class="org.jia.OrderItem">
<property name="orderdec" value="item00001"></property>
</bean>
<bean id="order" class="org.jia.Order" autowire="constructor">
<property name="orderNum" value="order000007"></property>
</bean>
</beans>
2.***aop***---代理
**Spring Security**為spring Security為spring應(yīng)用提供了生命式的安全機(jī)制絮蒿。
**Spring Boot**通過(guò)大量使用自動(dòng)配置技術(shù),可以取消大量的XML配置文件叁鉴,同時(shí)該框架提出了starter的概念土涝,用于簡(jiǎn)化pom文件』夏梗可以參考我的一系列博文:
### [《Spring Boot Cookbook》閱讀筆記](méi)(http://www.reibang.com/p/5ac18abc91f0)
**aop 應(yīng)用場(chǎng)景:**
>Authentication 權(quán)限
Caching 緩存
Context passing 內(nèi)容傳遞
Error handing 錯(cuò)誤處理
Lazy loading 懶加載
Debugging 調(diào)試
logging 但壮、tracing 、profiling and monitoring記錄跟蹤 優(yōu)化校準(zhǔn)
Performance optimization 性能優(yōu)化
Persistence 持久化
Resource pooling 資源池
Synchronization 同步
Transaction 事務(wù)
**如何使用Spring AOP**
>1.配置ProxyFactory常侣,顯式的設(shè)置advisors蜡饵、advice、target等
2.配置AutoProxyCreator胳施,
3.通過(guò)<aop:config>來(lái)配置
4.通過(guò)<aop:aspectj-autoproxy>使用AspectJ的注釋來(lái)表示通知以及切入點(diǎn)
**Spring提供了兩種方式實(shí)現(xiàn)代理:**
>1.JDKProxy動(dòng)態(tài)代理
2.Cglib
通過(guò)**<aop:config>**中的**proxy-target-class**屬性判斷溯祸,如果該屬性**被省略**或者為**false**---基于接口的代理起作用;如果該屬性為**true**---基于類(lèi)代理將起作用舞肆。
Spring中的AOP代理由Spring的IOC容器負(fù)責(zé)生成焦辅、管理,其依賴(lài)關(guān)系也有IOC容器負(fù)責(zé)管理椿胯。因此筷登,AOP代理可以直接使用容器中的其他bean實(shí)例作為目標(biāo),這種關(guān)系可以由IOC容器的依賴(lài)注入提供哩盲。Spring創(chuàng)建代理的規(guī)則為:
1前方、默認(rèn)使用Java動(dòng)態(tài)代理來(lái)創(chuàng)建AOP代理狈醉,這樣就可以為任何接口實(shí)例創(chuàng)建代理了
2、當(dāng)需要代理的類(lèi)不是代理接口的時(shí)候惠险,Spring會(huì)切換為使用CGLIB代理舔糖,也可強(qiáng)制使用CGLIB
AOP編程其實(shí)是很簡(jiǎn)單的事情,縱觀(guān)AOP編程莺匠,程序員只需要參與三個(gè)部分:
1金吗、定義普通業(yè)務(wù)組件
2、定義切入點(diǎn)趣竣,一個(gè)切入點(diǎn)可能橫切多個(gè)業(yè)務(wù)組件
3摇庙、定義增強(qiáng)處理,增強(qiáng)處理就是在A(yíng)OP框架為普通業(yè)務(wù)組件織入的處理動(dòng)作
**所以進(jìn)行AOP編程的關(guān)鍵就是定義切入點(diǎn)和定義增強(qiáng)處理遥缕,一旦定義了合適的切入點(diǎn)和增強(qiáng)處理卫袒,AOP框架將自動(dòng)生成AOP代理,即:代理對(duì)象的方法=增強(qiáng)處理+被代理對(duì)象的方法单匣。**
以下為簡(jiǎn)單實(shí)例:
aop.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
</beans>
兩個(gè)jar包:
1夕凝、aopalliance.jar
2、aspectjweaver.jar
開(kāi)始講解用Spring AOP的XML實(shí)現(xiàn)方式户秤,先定義一個(gè)接口:
public interface HelloWorld
{
void printHelloWorld();
void doPrint();
}
定義兩個(gè)接口實(shí)現(xiàn)類(lèi):
public class HelloWorldImpl1 implements HelloWorld
{
public void printHelloWorld()
{
System.out.println("Enter HelloWorldImpl1.printHelloWorld()");
}
public void doPrint()
{
System.out.println("Enter HelloWorldImpl1.doPrint()");
return ;
}
}
public class HelloWorldImpl2 implements HelloWorld
{
public void printHelloWorld()
{
System.out.println("Enter HelloWorldImpl2.printHelloWorld()");
}
public void doPrint()
{
System.out.println("Enter HelloWorldImpl2.doPrint()");
return ;
}
}
橫切關(guān)注點(diǎn)码秉,這里是打印時(shí)間:
public class TimeHandler
{
public void printTime()
{
System.out.println("CurrentTime = " + System.currentTimeMillis());
}
}
有這三個(gè)類(lèi)就可以實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Spring AOP了,看一下aop.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<bean id="helloWorldImpl1" class="com.xrq.aop.HelloWorldImpl1" />
<bean id="helloWorldImpl2" class="com.xrq.aop.HelloWorldImpl2" />
<bean id="timeHandler" class="com.xrq.aop.TimeHandler" />
<aop:config>
<aop:aspect id="time" ref="timeHandler">
<aop:pointcut id="addAllMethod" expression="execution(* com.xrq.aop.HelloWorld.*(..))" />
<aop:before method="printTime" pointcut-ref="addAllMethod" />
<aop:after method="printTime" pointcut-ref="addAllMethod" />
</aop:aspect>
</aop:config>
</beans>
寫(xiě)一個(gè)main函數(shù)調(diào)用一下:
public static void main(String[] args)
{
ApplicationContext ctx =
new ClassPathXmlApplicationContext("aop.xml");
HelloWorld hw1 = (HelloWorld)ctx.getBean("helloWorldImpl1");
HelloWorld hw2 = (HelloWorld)ctx.getBean("helloWorldImpl2");
hw1.printHelloWorld();
System.out.println();
hw1.doPrint();
System.out.println();
hw2.printHelloWorld();
System.out.println();
hw2.doPrint();
}
運(yùn)行結(jié)果為:
CurrentTime = 1446129611993
Enter HelloWorldImpl1.printHelloWorld()
CurrentTime = 1446129611993
CurrentTime = 1446129611994
Enter HelloWorldImpl1.doPrint()
CurrentTime = 1446129611994
CurrentTime = 1446129611994
Enter HelloWorldImpl2.printHelloWorld()
CurrentTime = 1446129611994
CurrentTime = 1446129611994
Enter HelloWorldImpl2.doPrint()
CurrentTime = 1446129611994
看到給HelloWorld接口的兩個(gè)實(shí)現(xiàn)類(lèi)的所有方法都加上了代理鸡号,代理內(nèi)容就是打印時(shí)間
**基于Spring的AOP使用其他細(xì)節(jié)**
1转砖、增加一個(gè)橫切關(guān)注點(diǎn),打印日志鲸伴,Java類(lèi)為:
public class LogHandler
{
public void LogBefore()
{
System.out.println("Log before method");
}
public void LogAfter()
{
System.out.println("Log after method");
}
}
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<bean id="helloWorldImpl1" class="com.xrq.aop.HelloWorldImpl1" />
<bean id="helloWorldImpl2" class="com.xrq.aop.HelloWorldImpl2" />
<bean id="timeHandler" class="com.xrq.aop.TimeHandler" />
<bean id="logHandler" class="com.xrq.aop.LogHandler" />
<aop:config>
<aop:aspect id="time" ref="timeHandler" order="1">
<aop:pointcut id="addTime" expression="execution(* com.xrq.aop.HelloWorld.*(..))" />
<aop:before method="printTime" pointcut-ref="addTime" />
<aop:after method="printTime" pointcut-ref="addTime" />
</aop:aspect>
<aop:aspect id="log" ref="logHandler" order="2">
<aop:pointcut id="printLog" expression="execution(* com.xrq.aop.HelloWorld.*(..))" />
<aop:before method="LogBefore" pointcut-ref="printLog" />
<aop:after method="LogAfter" pointcut-ref="printLog" />
</aop:aspect>
</aop:config>
</beans>
測(cè)試類(lèi)不變府蔗,打印結(jié)果為:
CurrentTime = 1446130273734
Log before method
Enter HelloWorldImpl1.printHelloWorld()
Log after method
CurrentTime = 1446130273735
CurrentTime = 1446130273736
Log before method
Enter HelloWorldImpl1.doPrint()
Log after method
CurrentTime = 1446130273736
CurrentTime = 1446130273736
Log before method
Enter HelloWorldImpl2.printHelloWorld()
Log after method
CurrentTime = 1446130273736
CurrentTime = 1446130273737
Log before method
Enter HelloWorldImpl2.doPrint()
Log after method
CurrentTime = 1446130273737
要想讓logHandler在timeHandler前使用有兩個(gè)辦法:
(1)aspect里面有一個(gè)order屬性,order屬性的數(shù)字就是橫切關(guān)注點(diǎn)的順序
(2)把logHandler定義在timeHandler前面汞窗,Spring默認(rèn)以aspect的定義順序作為織入順序
2姓赤、我只想織入接口中的某些方法
修改一下pointcut的expression就好了:
```
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<bean id="helloWorldImpl1" class="com.xrq.aop.HelloWorldImpl1" />
<bean id="helloWorldImpl2" class="com.xrq.aop.HelloWorldImpl2" />
<bean id="timeHandler" class="com.xrq.aop.TimeHandler" />
<bean id="logHandler" class="com.xrq.aop.LogHandler" />
<aop:config>
<aop:aspect id="time" ref="timeHandler" order="1">
<aop:pointcut id="addTime" expression="execution(* com.xrq.aop.HelloWorld.print*(..))" />
<aop:before method="printTime" pointcut-ref="addTime" />
<aop:after method="printTime" pointcut-ref="addTime" />
</aop:aspect>
<aop:aspect id="log" ref="logHandler" order="2">
<aop:pointcut id="printLog" expression="execution(* com.xrq.aop.HelloWorld.do*(..))" />
<aop:before method="LogBefore" pointcut-ref="printLog" />
<aop:after method="LogAfter" pointcut-ref="printLog" />
</aop:aspect>
</aop:config>
</beans>
```
表示timeHandler只會(huì)織入HelloWorld接口print開(kāi)頭的方法,logHandler只會(huì)織入HelloWorld接口do開(kāi)頭的方法