類掃描注解
案例
1、創(chuàng)建實(shí)例(Persion和Student)
@Component("persion")//相當(dāng)于<bean id = "persion" class = "../Persion"></bean>
public class Persion {
@Resource(name = "student")
private Student student;
public void say(){
student.say();
}
}
@Component("student")
public class Student {
public void say(){
System.out.println("student");
}
}
2、配置文件進(jìn)行配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package="spring.com.bxp.bean"></context:component-scan>
</beans>
3、測(cè)試
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Persion persion = (Persion) context.getBean("persion");
persion.say();
}
步驟:
1、啟動(dòng)Spring容器
2、Spring容器解析到類掃描注解解析器<context:component-scan base-package="spring.com.bxp.bean"></context:component-scan>的時(shí)候,在base-package指定的包及其子包下查找所有的類
3、查看哪些類上面含有@Component
4、如果注解的value屬性的值為空,則把類名的第一個(gè)字母變?yōu)樾?,作為id值,放入到Spring容器中
5、如果value屬性的值不為空,則使用value的值作為id值,放入到spring容器中。
6、在查找spring中的類的所有屬性,按照@Resource的規(guī)則進(jìn)行查找。
綜上所述,使用了類掃描機(jī)制的做法,配置文件中配置很簡(jiǎn)單,但是效率越來越低。
繼承
案例1
1、創(chuàng)建實(shí)例(Book, Persion, Student)
public class Book {
public void read(){
System.out.println("閱讀書籍");
}
}
public class Persion {
private Book book;
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
public void read(){
book.read();
}
}
public class Student extends Persion{
}
2、配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean id="persion" class="spring.com.bxp.bean.Persion">
<property name="bok" ref="book"></property>
</bean>
<bean id="student" class="spring.com.bxp.bean.Student"></bean>
<bean id="book" class="spring.com.bxp.bean.Book"></bean>
</beans>
3、測(cè)試
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) context.getBean("student");
student.read();
}
運(yùn)行結(jié)果出錯(cuò),空指針,說明在student中沒有繼承persion中book屬性的值。
解決辦法,在配置文件的student的bean上添加屬性parent
<bean id="student" class="spring.com.bxp.bean.Student" parent="persion"></bean>
案例二
1、創(chuàng)建實(shí)例
@Component
public class Book {
public void read(){
System.out.println("閱讀書籍");
}
}
@Component
public class Persion {
@Resource(name = "book")
private Book book;
public void read(){
book.read();
}
}
@Component
public class Student extends Persion{
}
2、配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package="spring.com.bxp.bean"></context:component-scan>
</beans>
3、測(cè)試
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) context.getBean("student");
student.read();
}
}
運(yùn)行結(jié)果正確
綜上連個(gè)案例:在使用繼承的過程中,在配置文件中給屬性賦值,需要使用parent屬性。使用注解給屬性賦值,則不需要。
AOP
切入點(diǎn)表達(dá)式

execution(public * *(..)):所有的公共方法
execution(* set*(..)) :代表所有的以set開頭的方法
execution(* com.xyz.server.AccountServer.*(..)):代表com.xyz.server包下的AccountServer類中的所有方法
execution( * com.xyz.server.*.*(..)):代表con.xyz.server包下的所有類中的所有方法
execution( * com.xyz.server..*.*(..)):代表con.xyz.server包及其子包下的所有類中的所有方法
第一個(gè)AOP程序
引入兩個(gè)jar包
aspectjrt.jar
aspectjweaver.jar
1、創(chuàng)建對(duì)象
public interface Dao {
void save();
void update();
}
public class DaoImpl implements Dao{
@Override
public void save() {
System.out.println("保存數(shù)據(jù)");
/**
* 此處書寫保存全部數(shù)據(jù)數(shù)據(jù)的程序
*/
}
@Override
public void update() {
/**
* 此處書寫更新數(shù)據(jù)的程序
*/
}
}
public class Transaction {
public void open(){
System.out.println("開啟事物");
}
public void commit(){
System.out.println("提交事物");
}
}
2、創(chuàng)建配置文件
引入以下名稱空間:
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
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-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<bean id="daoimpl" class="spring.com.bxp.proxy.DaoImpl"></bean>
<bean id="transaction" class="spring.com.bxp.proxy.Transaction"></bean>
<aop:config>
<!-- 切入點(diǎn) -->
<aop:pointcut expression="execution(* spring.com.bxp.proxy.DaoImpl.*(..))"
id="perform"/>
<!-- 切面 -->
<aop:aspect ref="transaction" >
<!-- aop:before:前置通知
aop:after-returning:后置通知
pointcut-ref:指向切入點(diǎn)表達(dá)式
-->
<aop:before pointcut-ref="perform" method="open"/>
<aop:after-returning pointcut-ref="perform" method="commit"/>
</aop:aspect>
</aop:config>
</beans>
3、測(cè)試類
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Dao dao = (Dao) context.getBean("daoimpl");
dao.save();
}
AOP步驟:
1、啟動(dòng)spring容器
2、實(shí)例化bean對(duì)象
3、spring容器 解析aop配置
(1)切入點(diǎn)表達(dá)式:把id對(duì)應(yīng)的類包含進(jìn)spring容器
(2)前置通知,后置通知
4、spring容器會(huì)按照切入點(diǎn)表達(dá)式所匹配的類在spring容器中進(jìn)行查找,如果找到該類,則會(huì)創(chuàng)建代理對(duì)象,如果找不到,則報(bào)錯(cuò)。
5、spring容器產(chǎn)生代理對(duì)象的方法:通知+目標(biāo)方法
6、客戶端通過context.getBean()得到一個(gè)對(duì)象,如果該對(duì)象有代理,則返回代理對(duì)象,如果沒有代理,則返回對(duì)象本身。
說明:1、客戶端通過context.getBean()得到一個(gè)對(duì)象,如果該對(duì)象有代理,則返回代理對(duì)象,如果沒有代理,則返回對(duì)象本身
2、如果目標(biāo)類實(shí)現(xiàn)了接口,則采用jvm生成代理對(duì)象,如果沒有實(shí)現(xiàn)接口,則采用cglib生成代理對(duì)象,而生成代理對(duì)象時(shí)候spring來做。
spring的通知:
前置通知:具有JoinPoint參數(shù)
/**
* 連接點(diǎn),代表一個(gè)方法,客戶端調(diào)用那個(gè)方法,那個(gè)方法就是連接點(diǎn)
*
* 通過參數(shù)可以獲取連接點(diǎn)的一些信息
* @param joinPoint
*/
public void open(JoinPoint joinPoint){
//獲取目標(biāo)類
joinPoint.getTarget();
//獲取連接點(diǎn)參數(shù)
joinPoint.getArgs();
//獲取連接點(diǎn)的名稱
joinPoint.getSignature().getName();
System.out.println("開啟事物");
}
<!-- aop:before:前置通知
pointcut-ref:指向切入點(diǎn)表達(dá)式
-->
<aop:before pointcut-ref="perform" method="open"/>
后置通知:
/**
* @param joinPoint:連接點(diǎn)
* @param val:接受目標(biāo)參數(shù)的返回值
*/
public void commit(JoinPoint joinPoint, Object val){
System.out.println("提交事物");
}
<!--
aop:after-returning:后置通知
val:和后置通知方法的參數(shù)名稱保持一致
-->
<aop:after-returning pointcut-ref="perform" method="commit" returning="val"/>
如果目標(biāo)方法遇到異常,后置通知將不執(zhí)行
最終通知:
/**
*
* @param joinPoint:連接點(diǎn)
*/
public void finallyMythod(JoinPoint joinPoint){
}
<aop:after method="finallyMythod" pointcut-ref="perform"/>
不管目標(biāo)方法是否遇到異常,最終通知都會(huì)執(zhí)行
異常通知:
/**
*
* @param joinPoint
* @param throwable:獲取目標(biāo)方法拋出的異常
*/
public void thowingMythod(JoinPoint joinPoint, Throwable throwable){
}
<!--
throwing:和通知中的異常參數(shù)名稱相同
-->
<aop:after-throwing method="thowingMythod" pointcut-ref="perform" throwing="throwable"/>
環(huán)繞通知:
public void arroundMythod(ProceedingJoinPoint joinPoint) throws Throwable{
joinPoint.proceed();//執(zhí)行目標(biāo)方法
}
applicationContext.xml
環(huán)繞通知可以控制目標(biāo)方法的執(zhí)行