在配置好需要的文件后就可以進行編程學(xué)習(xí)了疾渣。共郭。
Spring基于XML文件配置Bean的方法:
在IOC容器中配置:
<beans ... ...>
<bean id="helloWorld" class="com.spring.beans.HelloWorld">
<property name="name" value="spring"></property> //屬性注入
<property name="sex" value="man"></property>
<constructor-arg value="spring" ></constructor-arg> //構(gòu)造器注入
<constructor-arg value="sex"></constructor-arg>
<constructor-arg value="spring" index="0"></constructor-arg> //和上例效果相同
<constructor-arg value="sex" index="1">
<constructor-arg value="spring" type="String"></constructor-arg>
<constructor-arg value="sex" type="String"></constructor-arg>
</bean>
</beans>
1.創(chuàng)建spring的IOC容器
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
2.從IOC容器中獲取Bean的實例
HelloWorld helloWorld=(HelloWorld)ctx.getBean(HelloWorld.class); //只能有一個HelloWorld類型的Bean
HelloWorld helloWorld=ctx.getBean("helloWorld");
屬性配置細節(jié)
1.當(dāng)要給變量賦值特殊符號時可用<![CDATA["賦值內(nèi)容"]]>包裹起來豪筝。
2.屬性值也可以用 value 直接點進行配置
3.可以使用property的 ref 屬性建立 bean之間的引用關(guān)系符喝。
4.內(nèi)部 Bean 不能被外部影響威沫,只能內(nèi)部使用绩卤。
5.可以使用 <null/> 標(biāo)簽為某些屬性注入 null 值
6.使用級聯(lián)屬性賦值時,必須先初始化后才可以為級聯(lián)屬性賦值土涝,當(dāng)前 Bean 內(nèi)必須有 get和set -ref對象的方法佛寿。
7.使用<list>標(biāo)簽時,若引用的 Bean 是另一個包里的同名類,則應(yīng) import 另一個包的該同名類冀泻。
8.使用 util 標(biāo)簽來配置單例的集合bean常侣,以供多個bean進行引用,需要導(dǎo)入util命名空間弹渔。
9.使用 P命名空間為 bean 的屬性賦值胳施,需要導(dǎo)入p命名空間。相對于傳統(tǒng)的方式更加簡潔肢专。
格式 : <bean id="person" class="com.spring.beans.Person" p:name="name" p:age="15" ></bean>
10.可以使用 autowire 自動裝配舞肆,有byName,byType,constructor等方式。
<bean id="person" class="com.spring.beans.autowire.Person"
autowire="byName">
</bean>
11.bean之間的關(guān)系:bean 可以繼承 (parent)博杖、依賴(depends-on)椿胯,bean的abstract屬性為true,這樣的bean不能被IOC容器實例化剃根,只用來被繼承配置
不會繼承 bean 的所有屬性哩盲,例如:autowire、abstract……若某一個bean的 class 屬性沒有指定狈醉,則該 bean 必須是一個抽象 bean廉油。
depends-on 屬性會將 前置依賴的Bean在本Bean實例化之前創(chuàng)建好。如果依賴于多個Bean苗傅,則可以通過 逗號抒线、空格 配置Bean的名稱。
12.Bean的作用域 : 可以用 scope 屬性配置渣慕。 singleton 是默認(rèn)值十兢,容器初始時創(chuàng)建實例,在整個容器生命周期內(nèi)至創(chuàng)建這一個 bean摇庙。 prototype 是原型的旱物,容器初始化時不創(chuàng)建 bean 的實例,而是在每次請求時創(chuàng)建新的 bean實例并返回卫袒。
13.可以使用外部屬性文件配置Bean宵呛。<context:property-placeholder location="classpath: db.source" /> <property name="user" value="${user}">.
14.SpEL : 可以使用 SpEL 來給 Bean 配置 。
(1) 當(dāng)要給 字符串類型賦值時 : value="#{'abc'}"
(2) 當(dāng)賦 整型夕凝、浮點型時 : value="#{14}" value="#{123.321}"
(3) 當(dāng)引用其他 屬性時 : value="#{car}" value="#{car.price}"
(4) 當(dāng)引用類的靜態(tài)屬性時: value="#{T(java.lang.Math).PI*8}"
(5) 當(dāng)使用運算符時: value="#{ 10>5? '大于' : '小于' }"
-
可以自行設(shè)置 Bean 的 init()方法 和 destroy() 方法宝穗。 先在 Bean Class 里將init()和destroy()方法寫好,名字自訂码秉,然后在xml文件里配置逮矛。
例:<bean id="person" class="com.spring.beans.Person" init-method="init3" destroy-method="destroy"></bean>
16.可以添加 Bean后置處理器。通過寫一個 BeanPostProcessor 接口類转砖,然后在里面重寫 postProcessAfterInitialization(init后執(zhí)行)和postProcessBeforeInitialization(init前執(zhí)行) 方法须鼎,并在xml文件里配置鲸伴。
例:
<bean class="com.spring.beans.MyBeanPostProcessor"></bean>
17.可以使用靜態(tài)工廠方法配置bean:先創(chuàng)建一個靜態(tài)工廠方法類,例:
public class StaticGameFactory {
private static Map<String,Game> games=new HashMap<String,Game>();
static{
games.put("ChiJi", new Game("ChiJi",98));
games.put("H1Z1", new Game("H1Z1",68.0));
}
//靜態(tài)工廠方法
public static Game getGame(String name){
return games.get(name);
然后在xml文件里通過靜態(tài)工廠方法來配置bean晋控。
例:
<bean id="game" class="com.spring.beans.factory.Game" factory-method="getGame">
<constructor-arg value="cf"></constructor-arg></bean> //如果工廠方法需要傳入?yún)?shù)汞窗,則使用constructor-arg來配置參數(shù)
18.也可以使用實例工廠方法配置bean:
public class InstanceGameFactory {
private Map<String,Game> games;
public InstanceGameFactory(){
games=new HashMap<String,Game>();
games.put("CF", new Game("CF",0));
games.put("dnf", new Game("dnf",1));
}
public Game getGame(String name){
return games.get(name);
}
需要先配置工廠的實例:
<bean id="gameFactory" class="com.spring.beans.factory.InstanceGameFactory"></bean>
然后再配置 bean 實例: //factory-bean 指向?qū)嵗S方法的bean factory-method指向?qū)嵗S方法的名字; 如果工廠方法需要傳入?yún)?shù),則使用constructor-arg來配置參數(shù)
<bean id="game2" factory-bean="gameFactory" factory-method="getGame"><constructor-arg value="CF"></constructor-arg></bean>
19.通過FactoryBean 來配置 bean赡译。 首先自定義FactoryBean,需要實現(xiàn)FactoryBean 接口仲吏,然后在xml文件里 通過 FactoryBean 來配置Bean的實例,例:
class:指向FactoryBean的全類名蝌焚;property:配置FactoryBean的屬性裹唆; 實際返回的是 FactoryBean 的 getObejct() 方法的實例
<bean id="game" class="com.spring.beans.factorybeans.GameFactoryBean">
<property name="name" value="qwe"></property>
</bean>
20.通過注解配置Bean
<!-- 指定Spring IOC 容器掃描的包 -->
<!-- context:component-scan 子節(jié)點base-package="" 指定掃描該包及其子包 -->
<!-- 可通過 resource-pattern 指定掃描的資源 -->
<!--
<context:component-scan base-package="com.spring.beans.annotation"
resource-pattern="repository/*.class"
></context:component-scan>
-->
<!-- context:exclude-filter 子節(jié)點指定不包含哪些表達式的組件 -->
<!-- context:include-filter 子節(jié)點指定包含那些表達式的組件,該節(jié)點需要use-default-filters 配合使用(use-default-filters="false")-->
<context:component-scan base-package="com.spring.beans.annotation"
use-default-filters="true"><!-- type="annotation" 是掃描base-package 包及其所有子包-->
<!--
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
-->
<!-- type="assignable" 是掃描指定類及implements它的類 -->
<context:exclude-filter type="assignable" expression="com.spring.beans.annotation.repository.UserRepository" />
</context:component-scan>
使用@Autowired自動裝配Bean
一般情況下只洒,所有使用@Autowired注解的屬性都要被設(shè)置许帐,當(dāng)Spring找不到匹配的Bean時,會拋出異常红碑,若某一屬性允許不被設(shè)置舞吭,可以設(shè)置@Autowired 注解的 required 屬性 為fasle泡垃。
默認(rèn)情況下析珊,當(dāng)IOC容器里存在多個類型兼容的 Bean 時,通過類型的自動裝配將無法工作蔑穴,此時可以在 @Qualifier 注解里提供 Bean 的名稱忠寻,Spring 允許對方法的形參標(biāo)注 @Qualifier 以指定注入 Bean 的名稱。
--@Autowired 注解也可以應(yīng)用在 數(shù)組類型 的屬性上存和,此時Spring 會把所有匹配的 Bean 進行自動裝配奕剃。
--@Autowired 注解也可以應(yīng)用在 集合屬性 上,此時Spring 讀取該集合的類型信息捐腿,然后自動裝配所有與之兼容的 Bean纵朋。
--@Autowired 注解用在 java.util.Map 上時,若該 Map 的鍵值為 String 茄袖,那么 Spring 將自動裝配與之 Map 值類型兼容的 Bean 操软,此時Bean 的名稱作為鍵值。
21.泛型依賴輸入
public class BaseService<T> {
@Autowired
private BaseRepository<T> baseRepository;
public void add(){
System.out.println("add...");
System.out.println(baseRepository);
}
}
@Service
public class UserService extends BaseService<User>{
}
@Repository
public class UserRepository extends BaseRepository<User>{
}
當(dāng) userService 調(diào)用 add 方法時宪祥,會輸出
add...
com.spring.beeans.generic.di.UserRepository@2449a2da
22.動態(tài)配置(AOP基礎(chǔ)):
public class ArithmeticCalculatorLoggingProxy {
//要代理的對象
private ArithmeticCalculator target;
public ArithmeticCalculatorLoggingProxy (ArithmeticCalculator target) {
this.target=target;
}
public ArithmeticCalculator getLoggingProxy(){
//要代理的對象
ArithmeticCalculator proxy ;
//代理對象由哪一個類加載器負責(zé)加載
ClassLoader loader= target.getClass().getClassLoader();
//代理對象的類型聂薪,即其中有哪些方法
Class[] interfaces=new Class[]{ArithmeticCalculator.class};
//當(dāng)調(diào)用代理對象其中的方法時,該執(zhí)行的代碼
InvocationHandler h=new InvocationHandler() {
@Override
/*
* proxy:正在返回的那個代理對象蝗羊,一般情況下藏澳,在 invoke 方法中都不使用該對象
* method:正在被調(diào)用的方法
* args:調(diào)用方法時,傳入的參數(shù)
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("invoke...");
//日志
System.out.println("The method "+method.getName()+" begins with "+Arrays.asList(args));
//執(zhí)行方法
Object result=method.invoke(target, args);
//日志
System.out.println("The method "+method.getName()+" ends with "+result);
return result;
}
};
proxy=(ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);
return proxy;
}
}
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
public int add(int i, int j) {
return i+j;
}
public int sub(int i, int j) {
// TODO Auto-generated method stub
return i-j;
}
public int mul(int i, int j) {
// TODO Auto-generated method stub
return i*j;
}
public double div(double i, double j) {
return i/j;
}
}
public class Main {
public static void main(String[] args) {
ArithmeticCalculator target=new ArithmeticCalculatorImpl();
ArithmeticCalculator proxy=new ArithmeticCalculatorLoggingProxy(target).getLoggingProxy();
System.out.println(proxy.getClass().getName());
int result=proxy.add(1, 2);
System.out.println(result);
result=proxy.sub(3, 1);
System.out.println(result);
}
}
輸出結(jié)果為:
com.sun.proxy.$Proxy0
invoke...
The method add begins with [1, 2]
The method add ends with 3
3
invoke...
The method sub begins with [3, 1]
The method sub ends with 2
2
23.(1)SpringAOP
①加入JAR包 ②在配置文件中加入 aop 的命名空間
③基于注解的方式:
i.在配置文件中加入如下配置:
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean class="Aspect.class" / >
<!--掃描AOP和代理對象的類-->
<context:component-scan base-package="com.aop" />
AOP類:
@Aspect
public class LogginPerformance {
@Pointcut("execution(** com.aop.Performance.perform(..))")
public void cut() {}
@Before("cut()")
public void beforeMethod() {
System.out.println("Before");
}
}
代理對象類:
package com.aop;
public interface Performance {
public void perform();
}
還需要講implements 該接口類的 類 加入掃描對象
package com.aop;
@Component
public class Singer implements Performance{
@Override
public void perform() {
System.out.println("唱歌");
}
}
使用方法:
package com.aop;
@Component
public class TestAOP {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
Performance p=ctx.getBean(Performance.class);
p.perform();
}
}