SpringAOP的xml和注解两种实现方式

1、SpringAop的实现方案

Spring实现Aop有两种方案:JDK与CGLIB(Spring底层自动实现的)
点击此处可查看代理模式的代码实现

第一种方式:若目标对象实现了若干接口spring使用JDK的java.lang.reflect.Proxy类代理。

第二种方式:若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类。

注意事项:

1.对接口创建代理优于对类创建代理,因为会产生更加松耦合的系统。 对类代理是让遗留系统或无法实现接口的第三方类库同样 可以得到通知,这种方案应该是备用方案。

2.标记为final的方法不能够被通知。spring是为目标类产生子类。任何需要被通知的方法都被复写,将通知织入。final方法是不允许重写的。

2、maven导包

<!--引入spring需要的包-->
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>


        <!--spring-aop-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>

        <!--在配置文件里面用application-context-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>

        <!--测试-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <!--植入-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8</version>
        </dependency>
    </dependencies>


    <!--使用JDK1.8的配置-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>


        <!--加载xml-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/test/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>

    </build>

3、xml实现aop的方式

3.1项目结构

在这里插入图片描述

3.2 IUserService

package cn.itsource._08_springaop;

public interface IUserService {

    public void save();

    public void delete();

    public void update();
}

3.3 UserviceImpl

package cn.itsource._08_springaop;

public class UserviceImpl implements  IUserService {
    @Override
    public void save() {
        System.out.println("save");
    }

    @Override
    public void delete() {
        System.out.println("delete");
    }

    @Override
    public void update() {
        System.out.println("update");
    }
}

3.4 TxManager

package cn.itsource._08_springaop;


import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 这是一个模拟的假事务
 */

public class TxManager {

    public void begin(){
        System.out.println("开始事务...");
    }
    public void commit(){
        System.out.println("提交事务...");
    }
    public void rollback(Throwable e){
        System.out.println("回滚事务... 原因:"+e.getMessage());
    }
    public void close(){
        System.out.println("关闭事务...");
    }

    //自己写代码
    public void around(ProceedingJoinPoint joinPoint){
        //System.out.println(joinPoint.getArgs()); //参数
        //System.out.println(joinPoint.getSignature()); //方法签名(这个方法的所有信息都有)
        try {
            begin();
            joinPoint.proceed(); //执行对应的方法
            commit();
        } catch (Throwable e) {
            rollback(e);
        } finally {
            close();
        }
    }

}

3.4 重点:SpringTest-context.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<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
">

    <!--真实角色-->
    <bean class="cn.itsource._08_springaop.UserviceImpl" id="uservice"></bean>

    <!--增强对象-->
    <bean class="cn.itsource._08_springaop.TxManager" id="txManager"></bean>

    <!--
         aop配置
            切点写接口类,它会自动切所有的实现类
            *:任意返回值
            *:所有的方法
            (..):任意参数
            before在切点之前运行
            after-returning在切点之后运行
            after-throwing异常抛出,
            after最终通知
     -->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* cn.itsource._08_springaop.I*Service.*(..))"></aop:pointcut>
        <aop:aspect ref="txManager">
            <aop:before method="begin" pointcut-ref="pointcut"></aop:before>
            <aop:after-returning method="commit" pointcut-ref="pointcut"></aop:after-returning>
            <aop:after-throwing method="rollback" pointcut-ref="pointcut" throwing="e"></aop:after-throwing>
            <aop:after method="close" pointcut-ref="pointcut"></aop:after>
        </aop:aspect>
    </aop:config>

</beans>

3.6 测试SpringTest

注意:xml的配置文件名前面与测试名一致,那么@ContextConfiguration不用配置xml路径

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SpringTest {
    @Autowired
    private IUserService userService;

    @Test
    public  void TestBean(){
        userService.delete();

    }
}

3.7 打印结果

开始事务...
delete
关闭事务...
提交事务...

4、全注解实现aop(通常使用)

4.1项目结构

在这里插入图片描述

4.2 IUserService

public interface IUserService {

    public void save();

    public void delete();

    public void update();
}

4.3 UserviceImpl

@Service
public class UserviceImpl implements IUserService {
    @Override
    public void save() {
        System.out.println("save");
    }

    @Override
    public void delete() {
        System.out.println("delete");
    }

    @Override
    public void update() {
        System.out.println("update");
    }
}

4.4 SpringTest-context.xml

	<?xml version="1.0" encoding="UTF-8"?>
<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: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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
    <context:component-scan base-package="cn.itsource._09_aopanno"/>

    <!--配置aop注解支持-->
    <aop:aspectj-autoproxy />
</beans>

4.5 重点 TxManager

package cn.itsource._09_aopanno;


import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 这是一个模拟的假事务
 */
@Component
@Aspect
public class TxManager {

    @Pointcut("execution(* cn.itsource._09_aopanno.IUserService.*(..))")
    public void pointcut(){}
    @Before("pointcut()")
    public void begin(){
        System.out.println("开始事务...");
    }
    @AfterReturning("pointcut()")
    public void commit(){
        System.out.println("提交事务...");

    }
    @AfterThrowing(pointcut = "pointcut()",throwing = "e")
    public void rollback(Throwable e){
        System.out.println("回滚事务... 原因:"+e.getMessage());
    }
    @After("pointcut()")
    public void close(){
        System.out.println("关闭事务...");
    }
}

4.6 测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SpringTest {
    @Autowired
    private IUserService userService;

    @Test
    public  void TestBean(){
        userService.delete();
    }
}

4.7 打印结果

开始事务...
delete
关闭事务...
提交事务...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值