1.1 Spring的IOC註解開發
1.1.1 Spring的IOC註解開發入門
1.1.1.1創建Web項目引入jar包
- 在spring4版本中,除了引入基本的開發包外,還要引入aop包。
1.1.1.2引入spring的配置文件
- 在src下創建applicationContext.xml
- 引入約束:使用註解開發引入context約束
約束:spring-framework-4.2.4.RELEASE-dist\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
1.1.1.3 創建接口是實現類
1.1.1.4 開啓Spring的組件掃描
<!-- Spring的IOC註解入門 -->
<!-- 使用IOC的註解開發,配置組件掃描(那些包下的類使用IOC註解) ======-->
<!-- 掃描是爲了掃描類上的註解 -->
<context:component-scan base-package="com.itheima.spring"/>
1.1.1.5 在類上添加註解
@Component("userDao")//相當於<bean id="userDAO" class="com.itheima.spring.demo1.UserDaoImpl" >
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("Dao中保存的方法已經實現了。。。。"+name);
}
}
1.1.1.6 編寫測試類
@Test
//Spring的IOC註解的方式
public void demo2() {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao=(UserDao) applicationContext.getBean("userDao");
userDao.save();
}
1.1.1.7 註解方式設置屬性的值
註解方式:使用註解方式,可以沒有set方法的
- 屬性如果有set方法,需要將屬性注入的註解添加到set方法中
- 屬性如果沒有set方法,需要將屬性注入的註解添加到屬性中
@Component("userDao")//相當於<bean id="userDAO" class="com.itheima.spring.demo1.UserDaoImpl" >
public class UserDaoImpl implements UserDao {
@Value("東子")
private String name;
/* public void setName(String name) {
this.name = name;
}*/
public void save() {
System.out.println("Dao中保存的方法已經實現了。。。。"+name);
}
}
1.1.2 Spring的IOC的註解的詳解
1.1.2.1@Component:組件
1.1.2.2 屬性注入的註解
普通屬性:
- @value:設置普通屬性的值
對象類型屬性:
- @Autowired:設置對象類型的屬性值。但是按照類型完成屬性注入。
- 我們習慣是按照名稱完成屬性注入:必須讓@Autowired註解和@Qualifier一起使用完成按照名稱屬性注入。
- @Resource:完成對象類型的屬性注入,按照名稱完成屬性注入。
@Service("userService")//相當於<bean id="userService" class="com.itheima.spring.demo1.UserDaoImpl" >
public class UserServiceImpl implements UserService {
//注入DAO
/*@Autowired
@Qualifier(value="userDao")*/
@Resource(name="userDao")
private UserDao userDao;
public void save() {
System.out.println("Uservice的Dao。。。。");
userDao.save();
}
}
測試示例:
/**
* Spring註解開發的測試類
*/
public class SpringDemo1 {
@Test
//傳統方式
public void demo1() {
UserDao userDao=new UserDaoImpl();
userDao.save();
}
@Test
//Spring的IOC註解的方式
public void demo2() {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao=(UserDao) applicationContext.getBean("userDao");
userDao.save();
}
@Test
//Spring的IOC註解的方式
public void demo3() {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService) applicationContext.getBean("userService");
userService.save();
}
}
1.1.2.3 Bean的其他註解
生命週期相關的註解(瞭解)
- @PostConstruct :初始化方法
- @PreDestory :銷燬方法
Bean作用範圍的註解
@Scope :作用範圍
- singleton :默認單例
- prototype:多例
- request
- session
- globasession
@Service("customerService")//<bean id="" class="" init-method="init" destory-method="init"/>
@Scope("singleton")
public class CustomerService {
@PostConstruct//相當於init-method="init"
public void init() {
System.out.println("CustomerService的init方法執行了");
}
public void save() {
System.out.println("CustomerService的save方法執行了。。。");
}
@PreDestroy//相當於destory-method="init"
public void destory() {
System.out.println("CustomerService的destory方法執行了");
}
}
演示示例:
public class SpringDemo2 {
@Test
//生命週期演示
public void demo1() {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerService customerService=(CustomerService) applicationContext.getBean("customerService");
customerService.save();
}
}
1.1.3 IOC的XML和註解開發比較
1.1.3.1XML和註解的比較
試用場景
- XML:可以適用任何場景。結構清晰,維護方便。
- 註解:有些地方用不了,這個類不是自己提供的。開發方便。
1.1.3.2 XML和註解整合開發
XML完成管理Bean,註解完成屬性注入。
- 配置applicayionContext.xml
- OrderDao
- ProductDao
- ProductService
測試示例:
1.2 Spring的AOP的XML開發(****)
1.2.1 AOP概述
1.2.1.1 什麼是AOP
在軟件業,AOP爲Aspect Oriented Programming的縮寫,意爲:面向切面編程,通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生範型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。
1.2.1.2 Spring底層的AOP實現原理
動態代理
- JDK動態代理 :只能對實現了接口的類產生代理
- Cglib動態代理(類似於javassist第三方代理技術) :對於沒有實現接口的類產生代理對象,生成子類對象。
1.2.2 Spring的AOP底層實現(瞭解)
1.2.2.1 JDK動態代理
- 接口:
- 接口實現類:
- jdk動態代理類:
- 測試示例:
1.2.2.2 Cglib動態代理
Cglib:第三方開源代碼生成庫,動態添加類的屬性和方法。
- 被代理的類:
- Cglib的動態代理
/**
* Cglib的動態代理
*/
public class CglibProxy implements MethodInterceptor{
private CustomerDao customerDao;
public CglibProxy(CustomerDao customerDao) {
super();
this.customerDao = customerDao;
}
/**
* Cglib產生代理的方法
*/
public CustomerDao creatProxy() {
//1.創建Cglib的核心類對象
Enhancer enhancer=new Enhancer();
//2.設置父類(Cglib是通過繼承的方法取得代理對象)
enhancer.setSuperclass(customerDao.getClass());
//設置回調:(類似於InvocationHandler對象)
enhancer.setCallback(this);
//返回代理對象
CustomerDao proxy = (CustomerDao) enhancer.create();
return proxy;
}
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methosProxy) throws Throwable {
//判斷方法是否爲insert
if("insert".equals(method.getName())) {
System.out.println("增強了。。。。。。。。。。");
return methosProxy.invokeSuper(proxy, args);
}
return methosProxy.invokeSuper(proxy, args);
}
}
- 測試示例:
1.2.3 Spring的AOP的開發(AspectJ的XML的方式)
1.2.3.1 Spring的AOP的簡介
AOP思想最早是由AOP聯盟組織提出的。Spring是使用這種思想最好的框架。
Spring的AOP有自己實現的方式(非常繁瑣)。AspectJ是一個AOP的框架,Spring引入AspectJ作爲自身AOP的開發。
Spring兩套AOP開發方式。
- Spring傳統方式(棄用)
- Spring基於AspectJ的AOP的開發(使用)
1.2.3.2 AOP開發中相關術語:
1.2.4 Spring的AOP的入門(AspectJ的XML的方式)
1.2.4.1 創建Web項目,引入jar包
- 引入基本開發包
- 引入AOP開發的相關jar包
1.2.4.2 引入Spring的配置文件
- 引入aop的約束
約束:spring-framework-4.2.4.RELEASE-dist\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html
<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" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
1.2.4.3 編寫目標類並完成配置
- 接口
- 接口實現類
- 配置:
1.2.4.4 編寫測試類
- Spring整合Junit單元測試
1.2.4.5 編寫切面類
- 編寫切面類
- 將切面類交給spring
1.2.4.6 通過AOP的配置實現
1.2.5. Spring中通知類型
1.2.5.1 前置通知:在目標方法執行之前進行操作
- 前置通知:獲得切入點信息
1.2.5.2 後置方法:在目標方法執行之後進行操作
- 後置通知:獲得方法的返回值
1.2.5.3 環繞通知:在目標方法執行之前和之後進行操作
1.2.5.4 異常拋出通知:在程序出現異常的時候,進行的操作
- 獲得異常信息
1.2.5.5 最終通知:無論代碼是否有異常,總會執行。
1.2.5.6 引介通知(不會用)
代碼:
- 切面類:
/*
* 切面類
*/
public class MyAspectXML {
//前置通知
public void cheak(JoinPoint joinPoint) {
System.out.println("cheak run============"+joinPoint);
}
//後置通知
public void writeLog(Object resault) {
System.out.println("日誌記錄======"+resault);
}
//環繞通知
public Object round(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("環繞前通知。。。。。。。。");
Object obj = joinPoint.proceed();
System.out.println("環繞後通知。。。。。。。。");
return obj;
}
//異常拋出通知
public void afterThrowing(Throwable ex) {
System.out.println("異常拋出了。。。"+ex.getMessage());
}
//最終通知
public void after() {
System.out.println("最終通知-----------");
}
}
- 配置:
1.2.6 Spring的切入點表達式寫法
1.2.6.1切入點表達式語法
基於exception的函數完成的
語法:
- Public void com.itheima.spring.CustomerDao.save(..)
- * *.*.*Dao.save(..)
- * come.itheima.spring.CustomerDao+.save(..)
- * com.itheima.spring..*.*(..)