使用註解配置spring
步驟
1導包4(基本)+2(日誌)+spring-aop
2.爲主配置文件引入新的命名空間(約束)
3.開啓使用註解代理配置文件
4.在類中使用註解完成配置
將對象註冊到容器
修改對象的作用範圍
值類型注入
通過反射的Field賦值,破壞了封裝性
通過set方法賦值,推薦使用.
引用類型注入
重點
初始化|銷燬方法
package cn.itcast.bean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.xml.ws.RespectBinding;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
//<bean name="user" class="cn.itcast.bean.User" />
//@Component("user")
// @Service("user") // service層
// @Controller("user") // web層
@Repository("user")// dao層
//指定對象的作用範圍
@Scope(scopeName="singleton")
public class User {
private String name;
@Value("18")
private Integer age;
//@Autowired //自動裝配
//問題:如果匹配多個類型一致的對象.將無法選擇具體注入哪一個對象.
//@Qualifier("car2")//使用@Qualifier註解告訴spring容器自動裝配哪個名稱的對象
@Resource(name="car")//手動注入,指定注入哪個名稱的對象
private Car car;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public String getName() {
return name;
}
@Value("tom")
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@PostConstruct //在對象被創建後調用.init-method
public void init(){
System.out.println("我是初始化方法!");
}
@PreDestroy //在銷燬之前調用.destory-method
public void destory(){
System.out.println("我是銷燬方法!");
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", car=" + car + "]";
}
}
STS插件
spring與junit整合測試
1.導包4+2+aop+test
2.配置註解
3.測試
spring中的aop
aop思想介紹
spring中的aop概念
spring實現aop的原理
動態代理(優先)
被代理對象必須要實現接口,才能產生代理對象.如果沒有接口將不能使用動態代理技術
cglib代理(沒有接口)
第三方代理技術,cglib代理.可以對任何類生成代理.代理的原理是對目標對象進行繼承代理. 如果目標對象被final修飾.那麼該類無法被cglib代理.
動態代理:
package cn.itcast.c_proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import cn.itcast.service.UserService;
import cn.itcast.service.UserServiceImpl;
//觀光代碼=>動態代理
public class UserServiceProxyFactory implements InvocationHandler {
public UserServiceProxyFactory(UserService us) {
super();
this.us = us;
}
private UserService us;
public UserService getUserServiceProxy(){
//生成動態代理
UserService usProxy = (UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),
UserServiceImpl.class.getInterfaces(),
this);
//返回
return usProxy;
}
@Override
public Object invoke(Object arg0, Method method, Object[] arg2) throws Throwable {//代理對象,目標對象方法字節碼對象,方法參數
System.out.println("打開事務!");
Object invoke = method.invoke(us, arg2);
System.out.println("提交事務!");
return invoke;
}
}
cglib代理
package cn.itcast.c_proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import cn.itcast.service.UserService;
import cn.itcast.service.UserServiceImpl;
//觀光代碼=>cglib代理
public class UserServiceProxyFactory2 implements MethodInterceptor {
public UserService getUserServiceProxy(){
Enhancer en = new Enhancer();//幫我們生成代理對象
en.setSuperclass(UserServiceImpl.class);//設置對誰進行代理
en.setCallback(this);//代理要做什麼
UserService us = (UserService) en.create();//創建代理對象
return us;
}
@Override
public Object intercept(Object obj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
//原始對象、代理方法、參數、原始方法
//打開事務
System.out.println("打開事務!");
//調用原有方法
Object returnValue = methodProxy.invokeSuper(obj, arg);
//提交事務
System.out.println("提交事務!");
return returnValue;
}
}
測試:
package cn.itcast.c_proxy;
import org.junit.Test;
import cn.itcast.service.UserService;
import cn.itcast.service.UserServiceImpl;
public class Demo {
@Test
//動態代理
public void fun1(){
UserService us = new UserServiceImpl();
UserServiceProxyFactory factory = new UserServiceProxyFactory(us);
UserService usProxy = factory.getUserServiceProxy();
usProxy.save();
//代理對象與被代理對象實現了相同的接口
//代理對象 與 被代理對象沒有繼承關係
System.out.println(usProxy instanceof UserServiceImpl );//false
}
@Test
public void fun2(){
UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();
UserService usProxy = factory.getUserServiceProxy();
usProxy.save();
//判斷代理對象是否屬於被代理對象類型
//代理對象繼承了被代理對象=>true
System.out.println(usProxy instanceof UserServiceImpl );//true
}
}
aop名詞學習
spring中的aop演示
步驟(xml配置)
1.導包4(基本)+2(日誌)+2(spring的aop包)+2(spring需要第三方aop包)
spring的aop包:
spring-aspects-4.2.4.RELEASE.jar
spring-aop-4.2.4.RELEASE.jar
spring需要第三方aop包:
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2.準備目標對象
3.準備通知
4.配置進行織入,將通知織入目標對象中
步驟(註解配置)
1.導包4(基本)+2(日誌)+2(spring的aop包)+2(spring需要第三方aop包)
spring的aop包:
spring-aspects-4.2.4.RELEASE.jar、spring-aop-4.2.4.RELEASE.jar
spring需要第三方aop包:com.springsource.org.aopalliance-1.0.0.jar、com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2.準備目標對象
3.準備通知
4.配置進行織入,將通知織入目標對象中
一.註解代替xml配置
準備工作:
4+2 + spring-aop包
xml中導入context約束
在xml中開啓掃描包中類的註解
註解:
@Component("BeanName") 將對象註冊到spring容器
|- @Controler
|- @Service
|- @Repository
@Scope 指定對象的作用範圍
|- singleton
|- prototype
@Value 值類型屬性注入
@Autowired 自動屬性注入.根據類型注入.
@Qulifier 指定注入的對象的名稱
@Resource 指定對象的名稱注入
@PostConstruct 初始化方法
@PreDestory 銷燬方法
二.spring AOP開發
aop思想: 縱向重複,橫向抽取.
|- filter中
|- 動態代理
|- interceptor中
spring AOP: 封裝了動態代理技術.來體現aop.
springaop實現: 可以對所有對象進行代理
|- 動態代理 代理需要實現接口.
|- cglib代理 對目標對象繼承代理.
springaop名詞:
join point: 連接點.所有可以織入通知的方法.
point cut : 切入點.需要|已經織入通知的方法.
advice: 需要增強的代碼.
weaving: 動詞.將通知應用的切點的過程.
target: 目標對象.
proxy: 代理對象
aspect: 切面. 切入點+通知
步驟:
1.導包
4+2
2 aop+aspect
2 aop聯盟+weaving
2.準備目標對象
3.準備通知類
前置通知
後置通知 方法正常結束
環繞通知
異常攔截通知
後置通知 無論如何都執行
4.配置文件中配置,導入aop約束
1>目標對象
2>通知對象
3><aop:config>
<aop:ponint-cut id="切點名稱" expression="execution(切點表達式)" />
<aop:aspect ref="通知對象名稱" >
<aop:before method="" ponintcut-ref="" />
<aop:after-returning method="" ponintcut-ref="" />
<aop:around method="" ponintcut-ref="" />
<aop:after-throwing method="" ponintcut-ref="" />
<aop:after method="" ponintcut-ref="" />
</aop:aspect>
擴展:使用註解完成aop
1.導包
4+2
2 aop+aspect
2 aop聯盟+weaving
2.準備目標對象
3.準備通知類
4.配置文件中配置,導入aop約束
1>目標對象
2>通知對象
3><aop:aspect-autoproxy> 開啓註解aop
5.註解
@Aspect 指定當前類是通知類
@Before 前置通知方法
@after-returning 後置通知方法
@around 環繞通知方法
@after-throwing 異常攔截通知方法
@after 後通知方法
@PointCut 抽取切點表達式