Spring 第二天

使用Spring实现AOP

1.通过编程形式基于XML实现AOP(JDK动态代理)

 引入aspectjwarver环境


        <dependency>
           <groupId>org.aspectj</groupId>
           <artifactId>aspectjweaver</artifactId>
           <version>1.9.9.1</version>
       </dependency>

修改核心配置文件
 

<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>

增强通知类,两个通知

package com.csi.proxy;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

import java.util.Arrays;

public class TransactionManagerAdvice {
    public TransactionManagerAdvice(){
        System.out.println("开启数据库连接");
    }
    public void beforeT(JoinPoint joinPoint){
//        System.out.println("被增强的类"+joinPoint.getTarget().getClass().getName());
//        System.out.println("被拦截的方法"+joinPoint.getSignature().getName());
//        System.out.println("参数:"+ Arrays.toString(joinPoint.getArgs()));
        System.out.println("启动事务");
    }
    public void afterTreturning(JoinPoint joinPoint,Object o){
        System.out.println("事务提交");
    }

//    只有在运行时才会产生异常,因为运行时才会进行代理
    public void afterThrowing(JoinPoint joinPoint,RuntimeException e){
        System.out.println("产生了异常,事务回滚"+e.getMessage());
    }
    public void after(JoinPoint joinPoint){
        System.out.println("关闭资源");
    }


    /**
     * 环绕通知,灵活度低,可插拔性低,功能强大
     * @param pjp
     */
    public void afterAround(ProceedingJoinPoint pjp){
        //连接点
        System.out.println("开启事务");
        try {
            Object o = pjp.proceed();
            System.out.println("提交事务");
        } catch (Throwable e) {
            System.out.println("事务回滚");
           throw new RuntimeException(e);
        }finally {
            System.out.println("关闭资源");
        }
    }
}

连接点:Joinpoint,给一个连接点,对谁进行增强,对应要增强的方法。

切入点:   pointcut ,进行功能增强了的方法,没有被增强的不是切入点,是连接点

切面: 是描述通知和切入点的对应关系而组成的,也就是那些通知方法对应那些切入点方法

通知:在切入点前后执行的操作,也就是增强的共性功能,在SpringAOP中,功能最终以方

法的形式呈现。

通知类:通知方法所在的类就叫做通知类

 配置核心文件:

<bean id="userService" class="com.csi.service.impl.UserServiceImpl">
                <property name="userMapper" ref="userMapper"/>
            </bean>
                <bean id="userMapper" class="com.csi.mapper.impl.UserMapperImpl"/>
<bean id="txAdvice" class="com.csi.proxy.TransactionManagerAdvice"/>

                <aop:config>
                    <aop:pointcut id="pointcut" expression="execution(* com.csi.service..*.*(..))"/>
                    <aop:aspect ref="txAdvice">
<!--                        <aop:before method="beforeT" pointcut-ref="pointcut"/>-->
<!--                        <aop:after-returning method="afterTreturning" pointcut-ref="pointcut" returning="o"/>-->
<!--                        <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/>-->
<!--                        <aop:after method="after" pointcut-ref="pointcut"/>-->
<!--          环绕通知              -->
                        <aop:around method="afterAround" pointcut-ref="pointcut"/>
                    </aop:aspect>
                </aop:config>

 

expression(表达式)

execution(语法)

拦截对应方法,里面是*是任意类型

找到子包,子包下的所有类,所有类下的所有参数

expression="execution(*com.csi.service..*.*(..))"

配置通知类

配置->切入点->切面(引用通知 ref ,对功能进行同一增强,所有类中的所有方法)

测试类:

package com.csi;

import com.csi.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestTXManagerAdvice {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService1 = (UserService) ctx.getBean("userService");
        userService1.save();
        System.out.println();
        userService1.list();
    }
}

逻辑过程:

通过表达式,找到对应的切入点,切入进去再做拦截,切入service,拦截所有子包里的所有类的所有参数,之后做增强,配置一个增强类, 

异常通知,最终通知

此异常最准确的是在运行时产生的异常

    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* com.csi.service.impl.UserServiceImpl.list(..))"/>
        <aop:aspect ref="agentAdvice">
            <aop:before method="beforeT" pointcut-ref="pointcut"/>
            <aop:after-returning method="afterTreturning" pointcut-ref="pointcut" returning="o"/>
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/>
            <aop:after method="after" pointcut-ref="pointcut"/>
            
        </aop:aspect>
    </aop:config>

环绕通知

    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* com.csi.service.impl.UserServiceImpl.list(..))"/>
        <aop:aspect ref="agentAdvice">
            <!--                        <aop:before method="beforeT" pointcut-ref="pointcut"/>-->
            <!--                        <aop:after-returning method="afterTreturning" pointcut-ref="pointcut" returning="o"/>-->
            <!--                        <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/>-->
            <!--                        <aop:after method="after" pointcut-ref="pointcut"/>-->
            <!--          环绕通知              -->
            <aop:before method="before" pointcut-ref="pointcut"/>
        </aop:aspect>
    </aop:config>

 事务类,不是覆盖而是包含,环绕包含四种通知类型

package com.csi.proxy;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

import java.util.Arrays;

public class TransactionManagerAdvice {
    public TransactionManagerAdvice(){
        System.out.println("开启数据库连接");
    }
    public void beforeT(JoinPoint joinPoint){
//        System.out.println("被增强的类"+joinPoint.getTarget().getClass().getName());
//        System.out.println("被拦截的方法"+joinPoint.getSignature().getName());
//        System.out.println("参数:"+ Arrays.toString(joinPoint.getArgs()));
        System.out.println("启动事务");
    }
    public void afterTreturning(JoinPoint joinPoint,Object o){
        System.out.println("事务提交");
    }

//    只有在运行时才会产生异常,因为运行时才会进行代理
    public void afterThrowing(JoinPoint joinPoint,RuntimeException e){
        System.out.println("产生了异常,事务回滚"+e.getMessage());
    }
    public void after(JoinPoint joinPoint){
        System.out.println("关闭资源");
    }


    /**
     * 环绕通知,灵活度低,可插拔性低,功能强大
     * @param pjp
     */
    public void afterAround(ProceedingJoinPoint pjp){
        //连接点
        System.out.println("开启事务");
        try {
            Object o = pjp.proceed();
            System.out.println("提交事务");
        } catch (Throwable e) {
            System.out.println("事务回滚");
           throw new RuntimeException(e);
        }finally {
            System.out.println("关闭资源");
        }
    }
}

权限,到service层去判断,在调用方法之前判断,前置通知

package com.csi.proxy;

import org.aspectj.lang.JoinPoint;

public class AgentManageAdvice {
    public void before(JoinPoint joinPoint){
        System.out.println("先查数据库是否有权限...");

//        if (i==1){}else {throw new RuntimeException("");}

    }
}

日期格式注入

日期格式注入  

                    <bean id="address" class="com.csi.domain.Address"/>

                    <bean id="dateFormat" class="java.text.SimpleDateFormat">
                        <constructor-arg name="pattern" value="yyyy-MM-dd"/>
                    </bean>

                    <bean id="person" class="com.csi.domain.Person">
                        <constructor-arg name="bornDate">
                            <bean factory-bean="dateFormat" factory-method="parse">
                                <constructor-arg value="2022-02-22"/>
                            </bean>
                        </constructor-arg>
                    </bean>

List集合注入

    <bean id="student" class="com.csi.domain.Student"/>
                <property name="list">
                    <list>
                        <value>英语</value>
                        <value>数学</value>
                        <value>语文</value>
                    </list>
                </property>
    </bean>

Map集合注入

        <property name="map">
                    <map>
                        <entry key="1" value="1"/>
                        <entry key="2" value="2"/>
                        <entry key="3" value="3"/>
                    </map>
                </property>

属性文件注入

            属性文件    
                        <property name="properties">
                            <props>
                                <prop key="jdbc.className">com.mysql.cg.jdbc.Driver</prop>
                                <prop key="jdbc.url">jdbc:mysql://test</prop>
                                <prop key="jdbc.username">root</prop>
                                <prop key="jdbc.password">root</prop>
                            </props>
                        </property>

p标签注入,内部bean注入,ref注入

<bean id="address" class="com.csi.domain.Address"/>
      P标签注入少  
        <bean id="person" class="com.csi.domain.Person " p:address-ref="address" p:age="20" p:hello="world">
        </bean>

           内部bean注入         

       
            <bean id="person" class="com.csi.domain.Person " >
                <constructor-arg>
                    <bean class="com.csi.domain.Address"/>
                </constructor-arg>
            </bean>

            ref注入             

        <bean id="person1" class="com.csi.domain.Person " >
            <constructor-arg name="address" ref="address">
                
            </constructor-arg>
        </bean>
    两种注入类型      
1.property属性注入  
2.构造方法注入,少用吧 还有ref  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值