spring IOC 容器有兩種,分別是 BeanFactory 容器和 ApplicationContext 容器。java
BeanFactory以下:spring
/*第一步,利用ClassPathResource()API加載路徑CLASSPATH下的可用的Bean的xml配置文件 而後利用框架提供的 XmlBeanFactory() API生成工廠Bean,XmlBeanFactory()負責建立和初始化全部對象 而後用getBean方法獲得所須要Bean並轉化類型爲真正的對象 */ XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("Beans.xml")); HelloWorld obj = (HelloWorld) factory.getBean("helloWorld"); obj.getMessage();
<?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-3.0.xsd"> <bean id="helloWorld" class="com.tutorialspoint.HelloWorld"> <property name="message" value="Hello World!"/> </bean> </beans>
ApplicationContext接口的實現:數據庫
FileSystemXmlApplicationContext:從xml文件中加載已經被定義的bean,須要提供的參數爲完整的XML文件路徑express
ClassPathXmlApplicationCOntext:從xml文件中加載已經被定義的bean,但從CLASSPATH加載xml文件框架
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class MainApp { public static void main(String[] args) { //第一步 ApplicationContext context = new FileSystemXmlApplicationContext("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml"); //第二步 HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage(); } }
singleton:是bean的默認做用域;看成用域爲singleton時,IOC容器只會存在一個共享的bean實例,屢次getBean時,返回的都是同一個Bean函數
<bean id="..." class="..." scope="singleton"> <!-- collaborators and configuration for this bean go here --> </bean>
prototype:表示一個bean的定義對應多個對象實例,每次getbean時都會返回一個新的bean實例;ui
<!-- id是bean的id,用於識別bean; class是bean所對應的類--> <bean id="textEditor" class="com.tutorialspoint.TextEditor"> <!--constructor-arg表示基於構造函數注入 ,ref表示注入的值是引用而非通常的數值--> <constructor-arg ref="spellChecker"/> </bean>
<bean id="foo" class="x.y.Foo"> <!-- 當構造函數存在多個參數時,按順序定義便可按順序傳參--> <constructor-arg ref="bar"/> <constructor-arg ref="baz"/> </bean>
<bean id="textEditor" class="com.tutorialspoint.TextEditor"> <property name="spellChecker" ref="spellChecker"/> <!-- property表示基於設值函數注入,設值函數的名字必定要是 setSpellChecker()--> <property name="name" value="John Doe"/> <!-- name是屬性的名字,value是屬性的值--> </bean>
@required:用在set方法上,一旦用了這個註解,bean在初始化時就必須對這個值進行依賴注入;不然報錯this
public class Zoo { private Dog dog ; public Dog getDog() { return dog; } @required //若是xml文件中沒有對Dog屬性進行注入,則會報錯 public void setDog(Dog dog) { this.dog = dog; } }
@Autowired:能夠不寫依賴注入的配置,讓容器本身尋找依賴並注入spa
public class Zoo { @Autowired private Dog dog ; public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } }
在xml配置中添加下列語句,告訴spring要用註解的方式進行配置prototype
<context:annotation-config/>
import org.springframework.beans.factory.annotation.Autowired; public class Product {
private int id; //在屬性前加上Autowired註解,實現注入; //這時Category屬性就能夠不要set函數了,在xml中的Product的bean也不能再配置Category屬性了;但product的bean仍是須要的; //若是在xml中的product的bean中也配置了Category屬性,則會按照xml優先的原則尋找屬性對應的set函數或者構造函數,若是找不到則報錯 @Autowired private Category category; public int getId() { return id; } public void setId(int id) { this.id = id; } //也能夠在設值函數前加上Autowired註解,實現注入; //這種狀況下同上,能夠不用在xml文件中配置category屬性,但product的bean仍是須要聲明的 @Autowired public void setCategory(Category category) { this.category = category; } }
此時的xml:僅僅去掉了對屬性是引用的Category屬性的配置,其它的並無省略;(省略的是下方註釋的那一行)
<?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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> <bean name="c" class="com.how2java.pojo.Category"> <property name="name" value="category 1" /> </bean> <bean name="p" class="com.how2java.pojo.Product"> <property name="name" value="product1" /> <!-- <property name="category" ref="c" /> --> </bean> </beans>
先將xml中的什麼都去掉,只新增一行<context:component-scan base-package="com.how2java.pojo"/>,這時告訴spring,bean在哪一個java包下
<?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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.how2java.pojo"/> </beans>
而後在java文件中作以下改動
package com.how2java.pojo; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; //@component代表Product類是bean,這至關於在xml中聲明一個bean @Component("p") public class Product { //屬性的初始化如今放在屬性聲明中進行 private int id = 10; private String name="product 1"; //同上,對Category屬性進行自動注入 @Autowired private Category category; }
鏈接點(joinpoint):一個類或者一段程序擁有的具備邊界性質的特定點,叫作鏈接點。
切點(pointcut):是某些特定的鏈接點;若是用數據庫的概念來比喻鏈接點和切點的關係,鏈接點至關於客觀存在的記錄數據,而切點至關於查詢條件;
加強(advice):加強是織入到鏈接點上的一段程序代碼(就是一個方法);
目標對象:要被織入代碼的類
切面:切面 = 加強 + 切點
服務類:
import org.aspectj.lang.ProceedingJoinPoint; //加強所在的類 public class LoggerAspect { //加強,即要織入的方法 public void log(JoinPoint joinPoint) throws Throwable { System.out.println("start log"); return object; } }
xml配置:
<!-- 聲明業務類對象--> <bean name="s" class="com.how2java.service.ProductService"> </bean> <!-- 聲明服務類對象--> <bean id="loggerAspect" class="com.how2java.aspect.LoggerAspect"/> <aop:config> <!-- id是切入點的名字,定義了一個切點 --> <!-- expression 表示知足這個expression 的方法在被調用以後,就會執行切面操做,至關於觸發了切面;--> <!--第一個*表示返回值返回任意類型,第二個*表示任意方法,(..)表示方法的參數是任意數量和類型 --> <aop:pointcut id="loggerCutpoint" expression="execution(* com.how2java.service.ProductService.*(..)) "/> <!-- 定義了一個切面,切面 = 加強 + 切點--> <!-- id是切面的名字, ref是加強所在的類--> <aop:aspect id="logAspect" ref="loggerAspect"> <!-- pointcut-ref 表示本切面和哪一個切點相關聯; method表明加強--> <!-- aop:after 表示要在什麼時候調用加強;before在方法調用前,after在方法調用後,after-returning在方法執行成功後--> <!-- after-throwing在方法拋出異常後調用;around在方法調用前和調用後執行--> <aop:after pointcut-ref="loggerCutpoint" method="log"/> </aop:aspect> </aop:config>
業務類以下:
package com.how2java.service; import org.springframework.stereotype.Component; //用component來聲明這是一個bean @Component("s") public class ProductService { public void doSomeService(){ System.out.println("doSomeService"); } }
服務類以下:
package com.how2java.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; //Aspect註解表示這是一個切面,component註解聲明瞭一個bean @Aspect @Component public class LoggerAspect { //around註解表示對目標類中的某些方法進行切面操做 @Around(value="execution(*com.how2java.service.ProductService.*(..))") public Object log(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("start log:" + joinPoint.getSignature().getName()); Object object = joinPoint.proceed(); System.out.println("end log:" + joinPoint.getSignature().getName()); return object; } }
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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 下面兩行是告訴spring應該掃描哪些包--> <context:component-scan base-package="com.how2java.aspect"/> <context:component-scan base-package="com.how2java.service"/> <aop:aspectj-autoproxy/> </beans>