面试中对于IOC和AOP的理解

本文深入探讨了IOC(控制反转)的概念,解释了如何通过配置文件降低类之间的耦合度,以及IOC容器如何管理Bean的生命周期。同时,文章介绍了AOP(面向切面编程)的重要性,它允许将系统性任务如权限管理、事务处理和日志记录等从核心业务逻辑中剥离。JDK动态代理作为AOP的一种底层实现方式,通过InvocationHandler接口和Proxy.newProxyInstance()方法实现了方法调用前后的代码插入。

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

IOC

ioc意思是控制反转,它是一种思想而不是一种实现,他为什么叫控制反转呢,在传统代码中,我们某些类内部主动创建对象,从而导致类与类之间高耦合,使用IOC将类与类的依赖关系写在配置文件中,程序在运行时根据配置文件动态加载依赖的类,由IOC容器去实例化对象,这些在IOC容器中的对象叫做Bean,然后由IOC容器控制这些Bean的创建,销毁,降低类与类之间的耦合度。

AOP

这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。我们为何要使用aop?在软件开发过程中,有很多代码和业务逻辑无关但是会直接嵌入到业务逻辑代码中,使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。
底层实现:JDK动态代理:
要使用到 InvocationHandler 接口和 Proxy.newProxyInstance() 方法。
将一个被代理的对象注入一个中间对象,该中间对象要实现InvocationHandler接口,在实现该接口的时候,可以在被代理对象调用它的方法时,在调用前后插入一些代码,而 Proxy.newProxyInstance() 能够利用中间对象来生产代理对象。

public interface UserService {
    public void addUser(User user);
    public User getUser(int id);
}
public class UserServiceImpl implements UserService {
    public void addUser(User user) {
        System.out.println("add user into database.");
    }
    public User getUser(int id) {
        User user = new User();
        user.setId(id);
        System.out.println("getUser from database.");
        return user;
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyUtil implements InvocationHandler {
    private Object target;    // 被代理的对象
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("do sth before....");
        Object result =  method.invoke(target, args);
        System.out.println("do sth after....");
        return result;
    }
    ProxyUtil(Object target){
        this.target = target;
    }
    public Object getTarget() {
        return target;
    }
    public void setTarget(Object target) {
        this.target = target;
    }
}
import java.lang.reflect.Proxy;
import net.aazj.pojo.User;
public class ProxyTest {
    public static void main(String[] args){
        Object proxyedObject = new UserServiceImpl();    // 被代理的对象
        ProxyUtil proxyUtils = new ProxyUtil(proxyedObject);
        // 生成代理对象,对被代理对象的这些接口进行代理:UserServiceImpl.class.getInterfaces()
        UserService proxyObject = (UserService) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), 
                    UserServiceImpl.class.getInterfaces(), proxyUtils);
        proxyObject.getUser(1);
        proxyObject.addUser(new User());
    }
}

执行结果

do sth before....
getUser from database.
do sth after....
do sth before....
add user into database.
do sth after....
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值