国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring AOP面向切面編程實現及配置詳解

Spring AOP面向切面編程實現及配置詳解

2020-09-11 00:35Jimmyhe Java教程

這篇文章主要介紹了Spring AOP面向切面編程實現及配置詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

動態代理

特點

字節碼隨用隨創建,隨用隨加載

作用

不用修改源碼對方法增強

分類

基于接口的動態代理

基于子類的動態代理

創建

使用Proxy類中的newProxyInstance方法

要求

被代理類最少實現一個接口,沒有則不能使用

newProxyInstance方法參數

classLoader:類加載器

用于加載代理對象字節碼的,和被代理對象使用相同的類加載器

class[ ]:字節碼數組

用于讓代理對象和被代理對象有相同方法,固定寫法。

InvocationHandler:用于提供增強的代碼

是讓我們寫如何代理。一般都是寫一個該接口的實現類,通常情況下都是匿名內部類,不是必須的

此接口的實現類都是誰用誰寫

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
IProducer proxyProducer = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(),
    producer.getClass().getInterfaces(),
    new InvocationHandler(){
     作用:執行被代理對象的任何接口方法都會經過該方法
     * proxy 代理對象的引用
     * method 當前執行的方法
     * args 執行當前方法所需的參數
     * return 和被代理對象有相同的返回值
        @override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
            // 提供增強的代碼
            Object returnValue = null
            1. 獲取方法執行的參數
            Float money = (Float)args[0]
            2. 判斷當前方法是否為指定方法
            if("saleProduct".equals(method.getName())){
                returnValue = method.invoke(producer,money*0.8)
            }
            return returnValue;
        }
    }
)
//代理方法調用的是上面invoke中的方法
proxyProducer.saleProduct(100000)

注意 如果代理的類沒有接口,則代理不可用。

AOPxml配置

連接點Joinpoint:指那些被攔截的點,在spring中,這些點指的是方法,因為spring只支持方法類型的連接點。

切入點Pointcut:所謂切入點指的是要對哪些Joinpoint進行攔截的定義。方法會被增強。

所有的切入點都是連接點,但不是所有的連接點都是切入點。

通知Advice:指攔截到Joinpoint之后所要做的事情

在invoke方法里的,有前置通知,后置通知,異常通知,最終通知

引入Introduction

目標對象Target :即被代理的對象

織入Weaving:把增強應用到目標對象來創建新的代理對象的過程。Spring采用動態代理織入。

創建接口類,實現類

創建aop通知功能函數

xml配置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<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 https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
 
    <!--配置spring的IOC,把service對象配置進來-->
    <bean id="accountService" class="hjj.web.service.impl.AccountServiceImpl"></bean>
 
    <!--spring中基于xml的aop配置步驟
      1. 把通知bean也交給spring來管理
      2. 使用aop:config標簽表明aop的配置
      3. 使用aop:aspect標簽表明配置切面
        id:給切面提供一個唯一表示
        ref:指定通知類bean的id
      4. 在aop:aspect標簽的內部使用對應的標簽來配置通知的類型
        現在讓pringLog方法在切入點方法執行前執行
        aop:before表示配置前置通知
          method:用于指定Logger類中哪個方法是前置通知
          point屬性:用于指定切入點表達式,該表達式指的是對業務層中哪些方法增強
          切入點表達式:
            關鍵字:execution(表達式)
            訪問修飾符 返回值 包名.類名.方法名(參數列表)
            全通配寫法:* *..*.*(..)
              訪問修飾符可以省略 *可以代表任何返回值 *.*.*可以表示包的關系 *..表示中間任意包 *.* 表示類名和方法
              (..)表示任意參數或者可以寫返回值類型 int, java.lang.String
 
            實際開發寫法:切到業務層實現類下的所有方法 * 業務層包.*.*(..)
    -->
 
    <!--配置logger類-->
    <bean id="logger" class="hjj.web.utils.Logger"></bean>
 
    <!--配置AOP-->
    <aop:config>
      <!--配置切面-->
      <aop:aspect id="logAdvice" ref="logger">
        <!--配置通知類型,并且建立通知方法和切入點方法的關聯-->
        <aop:before method="printLog" pointcut="execution(public void hjj.web.service.impl.AccountServiceImpl.saveAccount())"></aop:before>
      </aop:aspect>
    </aop:config>
    
    // 通知類型
          <aop:aspect id="logAdvice" ref="logger">
        <!--配置通知類型,并且建立通知方法和切入點方法的關聯-->
<!--        <aop:before method="printLog" pointcut="execution(public void hjj.web.service.impl.AccountServiceImpl.saveAccount())"></aop:before>-->
        <aop:before method="beforePrintLog" pointcut="execution(* hjj.web.service.impl.AccountServiceImpl.saveAccount())"></aop:before>
        <aop:after-returning method="afterPrintLog" pointcut="execution(* hjj.web.service.impl.AccountServiceImpl.saveAccount())"></aop:after-returning>
        <aop:after-throwing method="afterThrowingPringLog" pointcut="execution(* hjj.web.service.impl.AccountServiceImpl.saveAccount())"></aop:after-throwing>
        <aop:after method="finalPrintLog" pointcut="execution(* hjj.web.service.impl.AccountServiceImpl.saveAccount())"></aop:after>
      </aop:aspect>
  
</beans>
?
1
2
3
4
<!-- 配置切入點表達式,ID屬性用于指定表達式的唯一標識,expression屬性用于指定表達式內容,此標簽也可以放在aspect外面-->
      <aop:pointcut id="pt1" expression="execution(* hjj.web.service.impl.AccountServiceImpl.saveAccount())"/>
      
<aop:before method="beforePrintLog" pointcut-ref="pt1"></aop:before>

AOPxml注解

aop注解配置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
 * 記錄日志的工具類,提供了公共的代碼
 */
@Component("logger")
@Aspect // 表示當前類是一個切面
public class Logger {
 
        @Pointcut("execution()")
        private void pt1(){}
  /**
   * 用于打印日志:計劃在其切入點方法執行前執行(切入點方法就是業務層方法)
   */
  @Before(pt1())
  public void beforePrintLog() {
    System.out.println("前置");
  }
 
  public void afterPrintLog() {
    System.out.println("后置");
  }
 
  public void afterThrowingPringLog() {
    System.out.println("異常");
  }
 
  public void finalPrintLog() {
    System.out.println("最終");
  }
 
  // 環繞通知為我們提供了ProceedingJoinPoint,有一個方法proceed(),此方法就明確了調用切入點方法
  // 為我們提供了一種可以在代碼中手動控制增強方法合適執行的方式
  public Object aroundPrintLog(ProceedingJoinPoint pjp) {
    Object returnValue = null;
    try {
      Object[] args = pjp.getArgs(); // 得到方法執行所需參數
 
      System.out.println("前置");
 
      returnValue = pjp.proceed(args); // 明確調用業務層的方法
 
      System.out.println("后置");
 
    } catch (Throwable throwable) {
//      throwable.printStackTrace();
      System.out.println("異常");
    } finally {
      System.out.println("最終");
    }
    return returnValue;
 
//    System.out.println("環繞通知");
  }
}

xml:

配置spring創建容器要掃描的包

<context:component-scan base-package="包路徑"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

注意 如果用注解自帶的調用順序會出現問題,用環繞通知順序正常

事務控制

導包

?
1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-tx</artifactId>
  <version>5.2.4.RELEASE</version>
</dependency>

事務管理器:org.springframework.orm.hibernate5.hibernate5.HibernateTransactionManager

在bean.xml中配置

1. 配置事物管理器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<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"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx
    https://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/aop
    https://www.springframework.org/schema/aop/spring-aop.xsd">
 
<bean id="transactionManager" class="org.springframework.orm.hibernate5.hibernate5.HibernateTransactionManager">
    <property name="dataSource" ref="dataSource">
<bean>

2.配置事物的通知

<tx:advice id="txAdvice" transaction-manager="transactionManager">

5.配置事物的屬性

?
1
2
3
4
5
6
7
8
9
10
11
12
13
    <tx:attributes>
        <tx:method name="*" propagation="required" read-only='false'/>
        <tx:method name="find*" propagation="support" read-only='true'/>
        
        isolation:指定事物的隔離級別,默認值是default,表示使用數據庫的默認隔離級別
        propagation:用于指定事物的傳播行為,默認是REQUIRED,表示一定會有事物,增刪改的選擇,查詢可以使用support
        read-only:用于指定事物是否只讀,查詢才設置為true
        timeout:用于指定事物的超市時間,默認值是-1,表示不超時,如果指定了數值,以秒為單位
        rollback-for:用于指定一個異常,當產生該異常時事物回滾,產生其他異常時,事物不回滾。沒有默認值,表示任何異常都回滾
        no-rollback-for:用于指定一個異常,當產生該異常,事務不會回滾,產生其他異常,事務回滾。沒有默認值,表示任何異常都回滾。
        
    </tx:attributes>
</tx:advice>

3.配置aop切入點表達式

<aop:config>
<aop:pointcut id="pt1" expression="execute(* 包.包.*.*(..))">

4. 建立切入點表達式喝事物通知的對應關系

<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1">
</aop>

<beans>

基于注解的事務控制

1. 配置事物管理器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx
    https://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/aop
    https://www.springframework.org/schema/aop/spring-aop.xsd"
    http://www.springframework.org/schema/context
    https://www.springframework.org/schema/context/spring-context.xsd">

3. 配置spring創建容器時要掃描的包

<context:component-scan base-package="包的地址">

4. 開啟spring對注解事物的支持

<tx:annotation-driven transaction-manager="transactionManager>"

6. 在需要事物支持的地方使用注解@Transactional

2.在實現類中

?
1
2
3
4
5
6
7
@Service(accountService)
@Transactional
public class 實現類 implements 接口類{
    @Autowired
    // 在持久層也要配置
    private IaccountDao accountDao
}

基于注解的配置類

1.創建一個配置總配置類

?
1
2
3
4
5
6
7
8
9
@Configuration
// 用于配置需要掃描的包
@ComponentScan("hjj.web")
@Import({HibernateConfig.class, TransactionConfig.class})
@PropertySource("hibernateConfig.properties")
@EnableTransactionManagement //開啟注解的支持
public class SpringConfiguration{
    
}

2.另一個java類,連接數據庫相關的類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
publci class HibernateConfig{
 
    @Value("${hibernate.username}")
    private String username;
    @Value("${hibernate.password}")
    private String password
 
    // 注入進容器
    @Bean(name="HibernateTemplate")
    public Hibernate crateHibernateTemplate(DataSource datasource){
        return new HibernateTemplate(dataSource)
    }
    
    @Bean(name="dataSource")
    public DataSource crateDataSource(){
        配置數據庫的用戶名密碼 創建數據源對象
    }
}

3. 新建一個properties,配置文件類

hibernate.username =
hibernate.password =

4. 創建和事物相關的配置類

?
1
2
3
4
5
6
7
public class TransactionConfig {
    //創建事務管理器對象
    @Bean(name="transactionManager")
    public PlatformTransactionManager createTransactionManager(DataSource dataSource){
        return new DataSourceTransactionManager(dataSource)
    }
}

5. main方法所在的類

?
1
2
3
4
5
6
@ContextConfiguration(classes=SpringConfiguration.class)
public class test{
    psvm{
        業務邏輯
    }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://www.cnblogs.com/jimmyhe/p/12592213.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲精品久久久久久一区二区 | 久久久免费 | 精品一区欧美 | 1区2区在线观看 | 国产美女啪啪 | 欧美成人精品一区二区 | 国产精品久久久久久久久久久免费看 | 欧美1页| 日韩欧美中文在线观看 | 国产精品九九九 | 久久国产精品一区二区三区 | 成人免费大片黄在线播放 | av网站一区| 欧美色视频在线观看 | 亚洲第一成人在线视频 | 国产亚洲精品久久久久动 | 国产精品中文在线 | 久久久久国产精品一区二区 | 欧美一区二区三 | 欧美黄色电影在线 | 日本一级淫片免费看 | 欧美黄色录像 | 免费a级毛片大学生免费观看 | 免费高清av | 偷拍自拍亚洲欧美 | 欧美成年黄网站色视频 | 国产精品久久久久久久久免费桃花 | 国产视频自拍一区 | 欧美1页| 亚洲福利电影网 | 蜜臀久久99精品久久久无需会员 | 成人在线免费观看 | 国产精品久久久久久久午夜片 | 日韩在线观看中文字幕 | 看亚洲a级一级毛片 | 欧美激情视频一区二区三区在线播放 | 亚洲一区中文字幕 | 看片久久| 欧美精品一区二 | 精品久久久久久久 | 国产成人综合av |