1.將全部的bean都配置xml中java
<bean id="" class="">spring
2.將全部的依賴都使用註解編程
@Autowired設計模式
默認不生效。爲了生效,須要在xml配置:<context:annotation-config>緩存
總結:安全
註解1:<context:component-scan base-package=" ">框架
註解2:<context:annotation-config>ide
1.通常狀況兩個註解不一塊兒使用。函數式編程
2. 「註解1」掃描含有註解(@Component 等)類,注入註解自動生效。函數
「註解2」只在xml和註解(注入)混合使用時,使注入註解生效。
AOP介紹
什麼是AOP
在軟件業,AOP爲Aspect Oriented Programming的縮寫,意爲:面向切面編程,經過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。AOP是OOP(面向對象編程)的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生範型。利用AOP能夠對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度下降,提升程序的可重用性,同時提升了開發的效率。
AOP採起橫向抽取機制,取代了傳統縱向繼承體系重複性代碼
經典應用:事務管理、性能監視、安全檢查、緩存 、日誌等
Spring AOP使用純Java實現,不須要專門的編譯過程和類加載器,在運行期經過代理方式向目標類織入加強代碼
AspectJ是一個基於Java語言的AOP框架,Spring2.0開始,Spring AOP引入對Aspect的支持,AspectJ擴展了Java語言,提供了一個專門的編譯器,在編譯時提供橫向代碼的織入
AOP實現原理
aop底層將採用代理機制進行實現。
接口 + 實現類 :spring採用 jdk 的動態代理Proxy。
實現類:spring 採用 cglib字節碼加強。
AOP術語【掌握】
1.target:目標類,須要被代理的類。例如:UserService
2.Joinpoint(鏈接點):所謂鏈接點是指那些可能被攔截到的方法。例如:全部的方法
3.PointCut 切入點:已經被加強的鏈接點。例如:addUser()
4.advice 通知/加強,加強代碼。例如:after、before
5. Weaving(織入):是指把加強advice應用到目標對象target來建立新的代理對象proxy的過程.
6.proxy 代理類
7. Aspect(切面): 是切入點pointcut和通知advice的結合
一個線是一個特殊的面。
一個切入點和一個通知,組成成一個特殊的面。
JDK動態代理 對「裝飾者」設計模式 簡化。使用前提:必須有接口
1.目標類:接口 + 實現類
2.切面類:用於存通知 MyAspect
3.工廠類:編寫工廠生成代理
4.測試
UserService.java
package com.jd.proxy.jdk; /** * @author weihu * @date 2018/8/15/015 23:35 */ public interface UserService { void addUser(); void updateUser(); void deleteUser(); }
MyAspect.java
package com.jd.proxy.jdk; /** * @author weihu * @date 2018/8/15/015 23:37 */ public class MyAspect { public void before(){ System.out.println("雞首"); } public void after(){ System.out.println("牛後"); } }
MyBeanFactory.java
package com.jd.proxy.jdk; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @author weihu * @date 2018/8/15/015 23:39 */ public class MyBeanFactory { public static UserService createService(){ // 1.目標類 UserService userService=new UserServiceImpl(); // 2.切面類 MyAspect myAspect=new MyAspect(); /* 3 代理類:將目標類(切入點)和 切面類(通知) 結合 --> 切面 * Proxy.newProxyInstance * 參數1:loader ,類加載器,動態代理類 運行時建立,任何類都須要類加載器將其加載到內存。 * 通常狀況:當前類.class.getClassLoader(); * 目標類實例.getClass().get... * 參數2:Class[] interfaces 代理類須要實現的全部接口 * 方式1:目標類實例.getClass().getInterfaces() ;注意:只能得到本身接口,不能得到父元素接口 * 方式2:new Class[]{UserService.class} * 例如:jdbc 驅動 --> DriverManager 得到接口 Connection * 參數3:InvocationHandler 處理類,接口,必須進行實現類,通常採用匿名內部 * 提供 invoke 方法,代理類的每個方法執行時,都將調用一次invoke * 參數31:Object proxy :代理對象 * 參數32:Method method : 代理對象當前執行的方法的描述對象(反射) * 執行方法名:method.getName() * 執行方法:method.invoke(對象,實際參數) * 參數33:Object[] args :方法實際參數 * */ UserService proxService = (UserService)Proxy.newProxyInstance( MyBeanFactory.class.getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //前執行 myAspect.before(); //執行目標類的方法 Object obj = method.invoke(userService, args); //後執行 myAspect.after(); return obj; } }); return proxService; } }
UserServiceImpl.java
package com.jd.proxy.jdk; /** * @author weihu * @date 2018/8/15/015 23:36 */ public class UserServiceImpl implements UserService{ @Override public void addUser() { System.out.println("proxy.jdk.addUser"); } @Override public void updateUser() { System.out.println("proxy.jdk.updateUser"); } @Override public void deleteUser() { System.out.println("proxy.jdk.updateUser"); } }
TestJDK.java
package com.jd.proxy.jdk; import org.junit.Test; /** * @author weihu * @date 2018/8/15/015 23:48 */ public class TestJDK { @Test public void testJDK(){ UserService userService=MyBeanFactory.createService(); userService.addUser(); userService.updateUser(); userService.deleteUser(); } }