javascript
Spring的核心思想,总结得非常好!
依賴注入是面型接口編程的一種體現,是Spring的核心思想。事實上依賴注入并不是什么高深的技術, 只是被Sping這么以包裝就顯得有些神秘。
class?Main?{interface?Language?{void?print(String s);}static?class?Java?implements?Language{@Overridepublic?void?print(String x)?{System.out.println("System.out.print(\""+ x +"\")");}}static?class?Coder?{private?Language lang =?new?Java();public?void?helloWorld()?{lang.print("hello world");}}public?static?void?main(String[] args)?{Coder coder =?new?Coder();coder.helloWorld();} } 如上代碼清單所示,Coder使用Java語言打印helloworld字符串, 在這里它不但依賴Language接口, 還依賴Java類,這使得它和Java類耦合在一起。要消除這種依賴或者說解耦很容易。 interface?Language?{void?print(String s); }static?class?Java?implements?Language{@Overridepublic?void?print(String x)?{System.out.println("System.out.print(\""+ x +"\")");} }static?class?Coder?{private?Language lang;public?void?setLang(Language lang)?{this.lang = lang;}public?void?helloWorld()?{lang.print("hello world");} }public?static?void?main(String[] args)?{Coder coder =?new?Coder();Language java =?new?Java();coder.setLang(java);coder.helloWorld(); }我們給Coder類增加了設置具體語言的方法,使得Coder類只依賴Language接口而不依賴具體的語言實現,換言之,Coder類和具體的語言解耦了,此時我們可以輕而易舉的使用其它語言代替Java,比如說使用C#。
static?class?CSharp?implements?Language{@Overridepublic?void?print(String x)?{System.out.println("Console.Write(\""+ x +"\")");} }public?static?void?main(String[] args)?{Coder coder =?new?Coder();Language csharp =?new?CSharp();coder.setLang(csharp);coder.helloWorld(); }這種在外部設置某個對象所依賴的具體對象的技巧就是依賴注入,這很很令人以外,一種最常見不過的編碼技巧居然還有如此高大山的名稱。
對于Coder類來說,確定使用何種語言原本實在編譯器期確定的,使用依賴注入后,使用何種語言便延時至運行期。
Spring框架的核心思想便是基于此,不過它的實現更進一步,它把創建各個對象設置依賴關系的過程動態化和通用化了。在我們的代碼清單中,創建對象和設置依賴關系的main方法只適用與當前的情況,而Spring的IOC容器能適用與任何情況
通常,Spring的依賴關系由XML表示,IOC容器解析XML完成對象的創建和依賴注入。
我們將之前的代碼用Spring框架來實現:
interface?Language?{void?print(String s); } class?Java?implements?Language{@Overridepublic?void?print(String x)?{System.out.println("System.out.print(\""+ x +"\")");} } class?CSharp?implements?Language{@Overridepublic?void?print(String x)?{System.out.println("Console.Write(\""+ x +"\")");} } class?Coder?{private?Language lang;public?void?setLang(Language lang)?{this.lang = lang;}public?Language?getLang()?{return?lang;}public?void?helloWorld()?{lang.print("hello world");} } 依賴關系將由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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean?id="java"?class="Java"></bean><bean?id="csharp"?class="CSharp"></bean><bean?id="coder"?class="Coder"><property?name="lang"?ref="csharp"></property></bean> </beans> 創建Coder對象的代碼變為 public?static?void?main(String[] args)?{ApplicationContext context =?new?FileSystemXmlApplicationContext("applicationContext.xml");Coder coder = (Coder) context.getBean("coder");coder.helloWorld(); } 具體的對象創建和依賴關系的設置將由IOC根據XML配置來完成,Spring使得依賴注入機制自動化,但是依賴注入的本質卻沒有變花。面向切面編程能實現不改變原有代碼的前提下動態的對功能進行增強, 比如說在一個方法執行前或執行后做某些事情如記錄日志、計算運行時間等等。
Spring中完美集成Aspectj,因此可以很方便的進行面向切面編程。
Spring Aspectj有幾個注解用以實現常用的面向切面編程功能
@Aspect public class Logger {@Before("execution(* controller.Default.*(..))")public void before(JoinPoint join){}@After("execution(* controller.Default.*(..))")public void after(){}@AfterReturning("execution(* controller.Default.*(..))")public void afterReturning() {}@AfterThrowing("execution(* controller.Default.*(..))")public void afterThrowing(){}@Around("execution(* controller.Default.*(..))")public void around(ProceedingJoinPoint jp) {} } 如上代碼所示, 此類對controller.Default類下的所有方法進行增強。@Before注解
@Before注解修飾的方法會在被增強的方法執行前被執行
@After注解
@After注解修飾的方法會在被增強的方法執行后被執行
@AfterReturning注解
@AfterReturning注解修飾的方法會在被增強的方法執行后被執行,但前提是被修飾的方法順利執行結束,假如方法中途拋出異常,那么AfterReturning注解修飾的方法將不會被執行,而After注解修飾的方法是無論如何都會被執行。
@AfterThrowing注解
@AfterThrowing注解修飾的方法會在被增強的方法執行出錯拋出異常的情況下被執行。
@Around注解
@Around注解是@Before注解和@After注解的綜合,它可以在被增強的方法的前后同時進行增強
@Around("execution(* controller.Default.*(..))") public?void?around(ProceedingJoinPoint jp)?{try?{System.out.println("before");jp.proceed();System.out.println("after");}?catch?(Throwable e) {System.out.println(e.getMessage());} } 使用此注解,被增強的方法需要手動編碼調用jp.proceed();
如果在增強代碼中不寫這一句,那么被增強的方法將不會運行。
此外, 還有一個重要的注解 @Pointcut
@Pointcut注解
此注解可以用來提煉切入點
@Aspect public class Logger {@Pointcut( value =?"execution(* controller.Default.*(..))")public void pointcut() {}@Before("pointcut()")public void before(JoinPoint join){}@After("pointcut()")public void after(){}@AfterReturning("pointcut()")public void afterReturning() {}@AfterThrowing("pointcut()")public void afterThrowing(){}@Around("pointcut()")public void around(ProceedingJoinPoint jp) {} }@Before、@After等注解可以應用此注解聲明的切入點,從而減少代碼的重復。
?
作者:Java程序媛環環
https://blog.csdn.net/Lubanjava/article/details/100084602
總結
以上是生活随笔為你收集整理的Spring的核心思想,总结得非常好!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员,Mybatis 你踩过坑吗?
- 下一篇: 教你用 Netty 实现一个简单的 RP