IoC AOP

BeanFactory

BeanFactory 是一个接口,提供了获取容器中Bean的相关方法。

BeanDefinitionRegistry 它才是IoC的容器,用于存储、管理所有的Bean对象。

DefaultListableBeanFactory 它是IoC容器的一个具体实现,实现了BeanFactory和BeanDefinitionRegistry接口,因此既拥有管理Bean的容器,又拥有访问Bean的方法。

BeanDefinition 每一个Bean都有一个BeanDefinition与之对应,用于存储Bean的相关信息:对象的class类型、是否是抽象类、构造方法参数等。RootBeanDefinition和ChildBeanDefinition是BeanDefinition的两个主要的实现类。

BeanDefinitionReader 在Spring中,标注Bean的依赖关系有四中方式:直接在代码setter、构造器中声明;通过XML文件声明;通过Properties文件声明;通过注解声明。BeanDefinitionReader接口的作用就是读取配置文件中的bean信息,把它们解析成BeanDefinition对象,然后注册到BeanDefinitionRegistry中去。PropertiesBeanDefinitionReader和XmlBeanDefinitionReader是该接口的两个实现类,分别用于解析properties和xml格式的配置文件。

初始化阶段

  1. 容器启动阶段 该阶段Spring会使用BeanDefinitionReader加载配置文件,并把所有的bean解析成BeanDefinition对象,并注册到BeanDefinitionRegistry。
  2. Bean实例化阶段 惰性加载,对于BeanFactory容器,当调用者主动调用getBean方法或者因存在依赖关系容器隐式调用getBean时,如果当前Bean尚未初始化,或者bean配置成prototype,就会触发Bean实例的初始化。

代理

可以实现业务逻辑和额外逻辑的解耦,在不修改委托类代码的情况下能够做一些额外的处理。

静态代理

若代理类在程序运行前就已经存在,那么这种代理方式称为静态代理,这种情况下的代理类通常都是我们在Java代码中定义的。静态代理可以通过聚合来实现,让代理类持有一个委托类的引用即可。继承同一个类或者接口,实现同样的方法,代理类加上自己额外的操作,再调用目标类的同样的方法。可以产生代理对象的静态代理工厂类,封装两个类。

动态代理

代理类在程序运行时创建的代理方式被成为 动态代理。 也就是说,这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类的函数。 

通过静态代理实现我们的需求需要我们在每个方法中都添加相应的逻辑,这里只存在两个方法所以工作量还不算大,假如包含上百个方法呢?这时候使用静态代理就会编写许多冗余代码。

在java的动态代理机制中,有两个重要的类或接口,一个是InvocationHandler接口、另一个则是 Proxy类,这个类和接口是实现我们动态代理所必须用到的。

public class DynamicProxy implements InvocationHandler { 
 
private Object obj; //obj为委托类对象;  

public DynamicProxy(Object obj) { 
    this.obj = obj;  
} 
 
@Override 
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("before"); 
    Object result = method.invoke(obj, args); 
    System.out.println("after"); 
    return result; 
    } 
 
} 
public class ProxyFactory {
    ...

    public static Object getDynProxy(Object target) {
        InvocationHandler handler = new DynProxyLawyer(target);
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
    }
}

 

首先Jdk的动态代理实现方法是依赖于接口的,首先使用接口来定义好操作的规范。然后通过Proxy类产生的代理对象调用被代理对象的操作,而这个操作又被分发给InvocationHandler接口的 invoke方法具体执行

 

CGLIB

CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

JDK代理要求被代理的类必须实现接口,有很强的局限性。而CGLIB动态代理则没有此类强制性要求。简单的说,CGLIB会让生成的代理类继承被代理类,并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。在CGLIB底层,其实是借助了ASM这个非常强大的Java字节码生成框架。
 

 

03-19
### Spring中的IOCAOP概念及其使用 #### IOC(控制反转) IOC的核心理念在于将对象的创建和管理权从应用程序转移到框架容器中。这种方式使得开发者无需手动实例化对象,而是让Spring容器负责管理和注入依赖项。 在传统的编程模式下,如果某个类需要另一个类作为其成员变量,则通常会通过`new`关键字显式地创建该类的实例。然而,在这种情况下,两个类之间存在紧密耦合的关系,这不仅增加了测试难度,还降低了代码的可维护性和扩展性[^1]。 为了克服这些问题,Spring引入了IOC机制。它允许开发者声明组件间的依赖关系,并由容器自动解析并提供所需的实例。具体来说: - **配置方式**:可以通过XML文件或者基于注解的方式来定义Bean以及它们之间的关联。 - **作用范围**:支持多种Scope选项,比如Singleton(单例)、Prototype(原型)等,默认为Singleton。 下面是一个简单的例子展示如何利用Java Config形式实现DI(Dependency Injection),这是IOC的一种表现形式之一: ```java @Configuration public class AppConfig { @Bean public MyService myService() { return new MyServiceImpl(); } } @Component class AnotherComponent { private final MyService service; @Autowired public AnotherComponent(MyService service){ this.service = service; } } ``` 上述代码片段展示了通过构造函数注入的方式实现了MyService到AnotherComponent里的绑定过程。 --- #### AOP(面向切面编程) AOP旨在解决横切关注点的问题——即那些无法清晰归属于单一模块却又广泛存在于整个应用的功能需求,例如日志记录、事务管理、安全性验证等等。传统OOP方法很难优雅地应对这类挑战,因为这些功能往往散布于多个业务逻辑之中,造成重复代码现象严重且不易修改。 借助Spring-AOP可以有效地分离这些跨领域职责,从而提高系统的模块化程度。主要特性如下: - **Join Point(连接点)**:程序执行流程中的某些特定位置,如方法调用前/后、抛出异常时等均可成为潜在的切入点。 - **Advice(通知)**:指明当达到指定join point时应采取的动作类型,包括Before Advice, After Returning Advice, Around Advice等多种形式。 - **Pointcut(切入点表达式)**:用于精确定位哪些join points会被拦截下来接受advice处理的一套规则集合。 - **Aspect(方面)**:把pointcuts 和 advices组合在一起形成完整的aop单元结构。 以下是采用@AspectJ风格编写的一个典型案例,演示了如何围绕目标服务添加额外的日志行为: ```java @Aspect @Component public class LoggingAspect { @Before("execution(* com.example.demo..*(..))") public void logBefore(JoinPoint joinPoint) { System.out.println("Method Name: " + joinPoint.getSignature().getName()); } } ``` 此段脚本设置了针对包路径下的任意公共方法进入之前打印名称的操作。 --- ### 总结 综上所述,IOC帮助简化复杂环境下的对象构建难题;而AOP则提供了强有力的工具集来集中处理分散在整个项目的通用任务。两者共同构成了现代企业级JAVA开发不可或缺的技术基石。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值