Spring_IoC注解開發和AOP的XML開發(學習筆記2)


一:IoC注解開發

1,在applicationContext.xml中需要引入context約束

1 <beans xmlns="http://www.springframework.org/schema/beans"
2     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3     xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
4         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
5         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
6 
7 </beans>

 

2,簡單的注解開發實例

 1   <!-- 進行IoC注解開發,首先在配置文件里配置組件掃描,即哪個包下的類進行注解開發 -->  
 2     <context:component-scan base-package="com.test.spring.demo1"/>
 3 
 4 @Component("userDao")
 5 public class UserDaoImp implements UserDao {
 6     @Value("三八")
 7     private String name;
 8     @Override
 9     public void save() {
10         System.out.println("UserDaoImp的save方法執行了"+name);
11     }
12     
13 }

 

注意:對於要實現的類中的屬性注入,可以不提供該屬性的set方法,如果提供了,將@Value的注解加在set方法上發即可

3,IoC注解詳情

@Component 

修飾一個類,將這個類交給Spring管理,有三個衍生注解(功能相似)建議用衍生的三個注解

  1. @Controller(web 層)
  2. @Service(service 層)
  3. @Repository(dao 層)
 1 @Repository("userDao")
 2 public class UserDaoImp implements UserDao {
 3     @Value("三八")
 4     private String name;
 5     @Override
 6     public void save() {
 7         System.out.println("UserDaoImp的save方法執行了"+name);
 8     }
 9     
10 }

 

屬性注入的注解

  • @Value(” “)注入普通屬性,並設置屬性的值
  • @Autowired    注入對象屬性,根據對象類型來注入,但一般是按照名稱來注入,需要搭配注解@Qualifier(value="名稱” 
  • @Resource(name="名稱")  根據名稱注入對象屬性,常用
 1 @Service("userService")
 2 public class UserServiceImp implements UserService {
 3     //注入UserDao
 4     /*@Autowired
 5     @Qualifier(value="userDao")*/
 6     @Resource(name="userDao")
 7     private UserDao userDao;
 8     @Override
 9     public void save() {
10         System.out.println("UserService的save方法執行了");
11         userDao.save();
12     }
13 }

 

其他注解:

  • @PostConstruct   初始化方法
  • @PreDestroy  銷毀方法
  • @Scope("singleton&prototype&request&session&globalsession")  作用范圍的注解,默認為singleton,單例
 1 @Service("customerService")
 2 @Scope
 3 public class CustomerServiceImp implements CustomerService {
 4     @PostConstruct
 5     public void Init(){
 6         System.out.println("init");
 7     }
 8     @Override
 9     public void save() {
10     }
11     @PreDestroy
12     public void Destroy(){
13         System.out.println("destroy");
14     }    
15 }

 

4,xml和注解的區別和整合開發

注解與XML配置的區別

注解:是一種分散式的元數據,與源代碼緊綁定。

xml:是一種集中式的元數據,與源代碼無綁定。

詳情:https://www.cnblogs.com/iOS-mt/p/6133656.html

xml和注解的整合開發(了解)

注意:bean管理交給xml,屬性注入交給注解

1 <bean id="customerService" class="com.test.spring.demo2.CustomerServiceImp"/>
2 <bean id="productDao" class="com.test.spring.demo2.ProductDao"/>
3 <!-- 需要開啟以下配置,在沒有掃描的情況下,能夠使用注解將屬性注入 @Value @Resource @Autowired @Qualifier-->
4 <context:annotation-config />

 

 二,AOP(Aspect Oriented Programming)面向切面編程

參考:http://www.cnblogs.com/xrq730/p/4919025.html

AOP的作用簡單圖示:

1,底層原理為動態代理(反射)

  • JDK動態代理:只能對實現了接口的類進行代理
  • Cglib動態代理:(類是於Javasist第三方代理技術),可以對沒有實現接口的類實現代理,生成子類對象
 1 //Cglib動態代理簡單實現,增強UserDao中的save方法
 2 public class UserDaoProxy implements MethodInterceptor{
 3     private UserDao userDao;
 4     
 5     public UserDaoProxy(UserDao userDao) {
 6         super();
 7         this.userDao = userDao;
 8     }
 9 
10     public UserDao createProxy(){
11         //1,獲取Cglib動態代理核心類
12         Enhancer enhancer=new Enhancer();
13         //2,設置父類
14         enhancer.setSuperclass(userDao.getClass());
15         //3,設置回調:(類似於    InvocationHandler對象)
16         enhancer.setCallback(this);
17         //4,創建代理對象
18         UserDao proxy = (UserDao) enhancer.create();
19         return proxy;
20     }
21 
22     @Override
23     public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
24         if("save".equals(method.getName())){
25             System.out.println("增強代碼");
26             return methodProxy.invokeSuper(proxy, args);
27         }
28         return methodProxy.invokeSuper(proxy, args);
29     }
30 }

2,AOP的相關術語:

  • Joinpoint(連接點,可以被增強/切入的方法都可以被稱為連接點)
  • Pointcut(切入點,真正被增強的連接點被稱為切入點)
  • Advice(通知/增強,增強的相關代碼或方法)
  • Introduction(引介,類層面的增強,即向類里直接加入增強的代碼)
  • Target(目標,被增強的對象)
  • weaving(織入,將Advice引入到Target的過程)
  • Proxy(代理,通過AOP織入后的類)
  • Aspect(切面,多個通知和多個切入點的組合)

注意:切入點可以是一個包下的單個類的單個方法,也可以是一個或多個包下的多個類的多個方法,需要靈活配置

3,基於aspectJ的aop的xml開發簡單入門

1)引入相應的jar包

2)在配置文件中引入aop的schema約束

1 <beans xmlns="http://www.springframework.org/schema/beans"
2     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3     xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
4         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
5         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->
6 
7 </beans>

 

3)編寫目標類

 1 public class ProductDaoImp implements ProductDao {
 2     
 3     @Override
 4     public void save() {
 5         System.out.println("product保存");
 6     }
 7     
 8     @Override
 9     public void delete() {
10         System.out.println("product刪除");
11     }
12     
13 }

 

4)編寫切面類

1 public class MyAspectXml {
2     public void checkPriviledge(){
3         System.out.println("權限校驗代碼=========");
4     }
5 }

 

5)xml的配置

 1  <!-- 配置目標對象 -->
 2     <bean id="productDao" class="com.test.demo1.ProductDaoImp"></bean>
 3     <!-- 配置切面類 -->
 4     <bean id="myAspect" class="com.test.demo1.MyAspectXml"></bean>
 5     <!-- 配置AOP對目標對象產生代理 -->
 6     <aop:config>
 7         <!-- 配置切入點 -->
 8         <aop:pointcut expression="execution(* com.test.demo1.ProductDaoImp.save(..))"
 9             id="pointcut1" />
10         <!-- 配置切面 -->
11         <aop:aspect ref="myAspect">
12             <aop:before method="checkPriviledge" pointcut-ref="pointcut1" />
13         </aop:aspect>
14     </aop:config>

 

4,advice(通知)類型

1)前置通知

僅能獲取到切入點信息(所有類型的通知都可以獲取)

1 public class MyAspectXml {
2     public void checkPriviledge(JoinPoint joinpoint){
3         System.out.println("權限校驗代碼========="+joinpoint);
4     }
5 }

 

2)后置通知

能夠獲取切入點的返回值

1 public void writeLog(Object obj){
2         System.out.println("日志代碼========="+obj);
3     }

 

1 <!-- 后置通知 -->
2 <aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="obj"/>    

 

3)環繞通知

在切入點的前后都執行相關的增強代碼,可以阻止切入點的執行(如對切入點進行事務處理)

1 public void round(ProceedingJoinPoint joinPoint) throws Throwable{
2         System.out.println("環繞前代碼========");
3         //執行切入點的方法
4         joinPoint.proceed();
5         System.out.println("環繞后代碼========");
6     }

1  <!-- 環繞通知 -->
2 <aop:around method="round" pointcut-ref="pointcut3"/>

 

4)異常通知

當所應用/通知的切入點,運行異常時,會執行異常通知,也可以對異常拋出

1 public void afterThrowing(Throwable ex){
2         System.out.println("異常拋出通知代碼====="+ex.getMessage());
3     }
4 
5   <!-- 異常通知 -->
6 <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>    

 

5)最終通知

無論切入點是否有異常,最終通知的代碼都會執行

1  <!-- 最終通知 -->
2 <aop:after method="after" pointcut-ref="pointcut4"/>

 

5,切入點表達式

execution([訪問修飾符] 訪問返回值類型 包名.類名.方法名(參數))

訪問修飾符可以省略,訪問返回值類型可以用 * 代替,表示任意類型,參數 .. 代替,表示任意參數 用 * 可以靈活配置切入點

例: * *.*.*(..)  表示任意包的的所有類下的說有方法配置為一個切入點

        * com.test.dao.UserDao+.save(..) 表示UserDao類及其子類的save方法配置為一個切入點


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM