由於前期不涉及到Web應用,所以不需要配置web.xml.
在src下創建xml(spring-beans.xml)文件。在xml文件中創建beans.
1. 當需要調用的時候,使用
- ApplicationContext ac=new ClassPathXmlApplicationContext("spring-beans.xml");
- ClassPathXmlApplicationContext與WebApplicationContext與FileSystemPathXmlApplicationContext
- WebApplicationContext允許從Web-Inf下開始尋找。
2. 獲取beans的三種常用方法
- Dog dog1=(Dog) ac.getBean("dog1");
- Dog dog2=ac.getBean(Dog.class);
- Dog dog3=ac.getBean("dog1",Dog.class);
3. Spring中的依賴注入,有三種
(1)屬性注入
set方法
IOC配置文件中,通過
><property name="屬性名稱" value="屬性的值">節點完成注入
需要在類中有set方法
(2)構造器注入
><使用construstor-arg value="" index=""></construstor-arg>
遇到多參數的實體類,多使用幾個construstor. 如果該實體類的參數有其他類的實例,那麼再注入的時候,需要在A bean中引用 B bean的實例。使用引用<ref bean="car1">.
也可以按照使用入參的類型來注入。
在注入value的時候,遇到特殊的值,可以使用<!CDATA[]>來傳值,進行強制解析。
(3)工廠方法注入--很少使用
4. 內部bean.類似於內部類,當bean A只會被 bean B 引用
5. bean可以使用自動裝配,需要在bean的autowire 屬性指定自動裝配的模式。二者不可兼容。
byType模式:若IOC容器中有多個與目標Bean類型一致的Bean,將無法判斷哪個bean最合適
byName模式: 必須將目標Bean的名稱與屬性名設置的一樣。
缺點:不夠靈活,當屬性過多時候,會都進行裝配,導致過重。
autowire只能二者選一,不能兼容。
在實際開發中,清晰明確的配置文件更好。
6. bean的作用域分四種:
(1)Signleton IOC容器默認作用域是單實例bean,當容器加載時候只會創建唯一一個實例。整個IOC容器範圍都能共享該實例。後續所有調用bean都將返回一個對象。
(2)prototype.每次調用都會返回一個新的對象
(3)request 每次Http請求都會創建一個新的Bean,但是該作用域僅僅適用於WebApplicationContext.
(4)session,同一個Http Session共享一個Bean,該作用域僅僅適用於WebApplicationContext.
7. 引用外部屬性文件,完成屬性注入。實現解耦操作,每次修改不需要改動xml文件。例如數據源對象,不能寫在xml文件中。Sping提供了一個PropertyPlaceholderConfigurer的BeanFactory後置處理器。這個處理器允許將value移動到外部文件中。
(1)創建 *.properties. key=value
(2)在xml中,引用key需要使用${}。
(3)告知IOC容器需要使用的properties文件
- <context:property-placeholder location="classpath:person.properties"/>
8. springEL表達式:
(1)訪問bean中的某個屬性。如#{person1.name}
(2) 可以進行基本的運算,如加減乘除等。如 #{person1.age *10}
9. Bean的生命週期,spring允許在bean的生命週期的特定點執行特定的任務。
生命週期包括:
(1) 通過構造器方法或者工廠方法創建bean
(2)爲bean的屬性設置值和對其他bean的引用
(3)後置處理器前置處理
(4)調用bean的初始化方法 init-method
(5)後置處理器後置處理
>後置處理實現postPorcessAfterInitialization(Object bean,String beanName)
(7)調用bean的銷燬化方法destory-method
10. 後置處理器
(1).bean後置處理器允許在調用初始化方法前後對bean進行額外處理
(2).bean後置處理器對所有bean實例逐一處理,而非單一實例。例如根據某些標準更改bean屬性。
(3).對bean後置處理器,需要實現beanPostProcessor接口。
(4).前置處理實現 postPorcessBeforeInitialization(Object bean,String beanName)
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("之前");
return bean;
}
(5).後置處理實現postPorcessAfterInitialization(Object bean,String beanName)
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("之後");
return bean;
}
(6). 在spring-bans.xml中爲該處理器設置bean.
<bean id="beanProcessor" class="com.spring.beans.MyBeanProcessor"/>
11. 靜態工廠方法與實例工廠方法創建bean
(1)區別:靜態工廠通過類名直接就去調用,在調用的時候已經存在一個工廠,而實例工廠需要在調用的時候先去創建工廠。
(2)靜態工廠方法創建bean:
<bean id="dateFormat" class="java.text.DateFormat" factory-method="getDateInstance">
<constructor-arg value="2"></constructor-arg>
</bean>
調用:
DateFormat df=(DateFormat) ac.getBean("dateFormat");
(3)實例工廠方法創建Bean,將對象的創建過程封裝在另外一個對象實例中,當需要請求該對象的時候,只需要簡單的調用該實例方法而不需要關心對象的創建過程,實現解耦操作。
<bean id="simpleDateFormat" class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-MM-dd hh-mm-ss"></constructor-arg>
</bean>
<bean id="date" factory-bean="simpleDateFormat" factory-method="parse">
<constructor-arg value="2012-12-12 12-12-12"></constructor-arg>
</bean>
在創建date的時候,只需要指定方法名,加上參數。而不需要關注具體使用的是那種類。
12. 通過FactoryBean的方式來創建bean.
需要創建一個類,繼承FactoryBean。
public class MyFactoryBean implements FactoryBean<Object> {
@Override
public Object getObject() throws Exception {
Dog dog=new Dog();
dog.setType("博美");
return dog;
}
@Override
public Class<?> getObjectType() {
return Dog.class;
}
@Override
public boolean isSingleton() {
// TODO Auto-generated method stub
return false;
}
}
13. 使用註解方式自動裝配bean
(1)在pring-beans.xml中,增加自動掃描包
<context:component-scan base-package="com.spring.beans"></context:component-scan>
(2)在實體中使用@component. 如果不指定id,默認是類名的首字母小寫。
(3)同理,還有其他的註解。@Controller,用來配置action控制層。@service用來代表業務層。@Repository用來標註dao層。
14. 使用註解方式自動注入bean的屬性
(1) @Autowired.按照類型自動注入,如果IOC容器中存在多個類型,拋出異常。Autowird會有很多問題,一般不常見
@Autowired
private MyDao myDao;
(2)@Resource按照名字來裝配。
(3)@Inject跟@Autowired類似,但是沒有required的屬性,當required=false,表示不需要進行注入。
15. AOP
切面(Aspect) 橫切關注點的模塊化(抽象),具有相同功能的模塊點可以抽象成一個切面。比如校驗數據模塊與日誌加載模塊可以抽象成兩個切面。
連接點:spring允許加入通知的地方:,共同業務和核心業務分離的點。前置、後置、異常處理等。
切點:可以通過切點定位到某一個特定的連接點。
(1) 先創建一個Aspect類,用來存放具體分離開的代碼。
(2)共同的業務加入到切面,
(3)前置通知、後置通知。@Before
//引用註解,表示該方法是切面
@Aspect@Component
public class ComputerAspect {
/**
* execution(public void com.spring.beans.service.impl.ComputerServiceImpl.add())
* 這是切點表達式,將需要處理的function全路徑放在這裏。
* 如果需要加參數,可以使用類似add(int,int)
*/
@Before(value = "execution(public void com.spring.beans.service.impl.ComputerServiceImpl.add())")
public void before(){
System.out.println("調用function之前");
}
@After("execution(public void com.spring.beans.service.impl.ComputerServiceImpl.add())")
public void after(){
System.out.println("調用function之後");
}
}
(4)在spring-ban.xml中,增加切面標籤。aspect註解的類自動生成代理。
<app:aspect-autoproxy></app:aspect-autoproxy>
記得導入AOP的命名空間與AOP的xsd文件。