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

本文介绍了如何在Java项目中使用Spring AOP进行面向切面编程,通过实例展示了从model层到controller层的四层体系结构,并详细解释了如何创建并配置切面类PrintLog,以此实现代码的切面处理,提高代码的可维护性和完整性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值