Spring aop(Aspect Oriented Programming:面向切面编程)入门

java框架使用入门 专栏收录该内容
2 篇文章 0 订阅

在这个炎炎夏日,我渴望透心凉,那么你也要来一瓶吗?

从来没人告诉我们做一件事养成好的习惯有多么至关重要,只是告诉我们这个对那个不对,也许事与愿违,但我们都想往好的方向发展。那么今天我们就要从好的方面开始做起。

在做一个项目的时候,首先明确分包是一个锻炼统筹能力的好的开端,从模仿中我们可以总结-归纳-演绎,直至达到巅峰,没错盖世神功就是这样炼成的。

java项目的四层体系分别是model层,dao层,service层,controller层,从四层体系中来接触aop怎么使用

首先在model包下我们创建User类

public class User {

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User: id = " + id
                + " name = " + name;
    }
}

在dao包下面创建数据访问层IUserDao接口

//数据访问层
public interface IUserDao {

    void add(User user);
}

创建UserDao使用repository注解

//等于完成了<bean id="userDao" class="com.spring.dao.UserDao"/>
//@Repository一般用于DAO的注入
@Repository
public class UserDao implements IUserDao {
    @Override
    public void add(User user) {
        System.out.println("add:"+ user);
    }
}

在service包下创建业务层IUserService接口

public interface IUserService {

    void add(User user);
}

创建UserService使用service注解 持有IUserDao 自动装配

// 业务层一般使用service
@Service
public class UserService implements IUserService {

    @Autowired
    private IUserDao userDao;

    @Override
    public void add(User user) {
        userDao.add(user);
    }

}

在controller包下创建UserController

//控制层使用controller注解 Scope定义为多例,默认单例
@Controller
@Scope("prototype")
public class UserController {

    private User user;
    @Autowired
    private IUserService userService;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public void add(){
        userService.add(user);
    }
}

接下来重点来了,创建PrintLog类使用component注解,来展示我们的AOP使用

//打印日志记录
@Component
public class PrintLog {

    public void start(JoinPoint joinPoint){
//        执行的对象
        System.out.println(joinPoint.getTarget());
//        执行的方法名
        System.out.println(joinPoint.getSignature().getName());
        Logger.i("开始打印");
    }
    public void end(){
        Logger.i("结束打印");
    }
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Logger.i("around中加入日志");
//        执行程序
        proceedingJoinPoint.proceed();
        Logger.i("结束around");
    }
}

这里我创建了Logger工具类

public class Logger {
    public static void i(String s){
        System.out.println("=========="+s);
    }
}

创建beans.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/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<!--打开Spring的Annotation支持-->
    <context:annotation-config/>
    <!--设定Spring找Annotation-->
    <context:component-scan base-package="com.spring"/>
    <!-- 例如定义切入点表达式 execution(* com.sample.service.impl..*.*(..))
    整个表达式可以分为五个部分:
    1、execution(): 表达式主体。
    2、第一个*号:表示返回类型,*号表示所有的类型。
    3、包名:表示需要拦截的包名,(“.*”表示包下的所有类) 而“..*”表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
    4、其中第二个*号:是表示类名。
    5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。-->
    <aop:config>
        <!--定义切面-->
        <aop:aspect id="testAspect" ref="printLog">
            <!--要加入aspect的位置-->
            <aop:pointcut id="testPointCut" expression="execution(* com.spring.dao.*.add*(..))"/>
            <!--在之前加入-->
            <aop:before method="start" pointcut-ref="testPointCut"/>
            <!--环绕-->
            <aop:around method="around" pointcut-ref="testPointCut"/>
            <!--在之后加入-->
            <aop:after method="end" pointcut-ref="testPointCut"/>
        </aop:aspect>
    </aop:config>
</beans>

编写测试代码:

public class Main {

//    public static void main(String[] args) {
//        System.out.println("Hello World!");
//    }
    private BeanFactory factory = new ClassPathXmlApplicationContext("beans.xml");

    @Test
    public void testUserAOP(){
        UserController userController = factory.getBean("userController",UserController.class);
        User user = new User();
        user.setId(100);
        user.setName("nickName");
        userController.setUser(user);
        userController.add();
    }
}

输出信息:

com.spring.dao.UserDao@1887735
add
==========开始打印
==========around中加入日志
add:User: id = 100 name = nickName
==========结束around
==========结束打印

PS:在四层体系中controller调用service,service调用dao,dao又持有model原型,中间穿插切面编程,只需要在beans.xml中配置一下,一点都不会破坏代码的完整性,当然我们使用注解还简化了一部分代码,实乃神兵利器。

DEMO

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

_高sir

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值