IoC(控制反转)是一种设计思想,将原本需要在程序中手动创建对象的控制权,交由Spring框架来管理。IoC容器是Spring用来实现IoC的载体,IoC容器实际上就是一个Map(Key,value),Map中存放的是各种对象。
将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。IoC容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何创建的。
Spring IoC初始化过程:

如何解决循环依赖
使用三级缓存。
第一级缓存singletonObjects里面放置的是实例化好的单例对象。
第二级earlySingletonObjects里面存放的是提前曝光的单例对象(没有完全装配好)。
第三级singletonFactories里面存放的是要被实例化的对象的对象工厂。
AOP(面向切面编程)核心思想是将业务逻辑中与类不相关的通用功能切面式的提取分离出来,让多个类共享一个行为,一旦这个行为发生改变,不必修改类,而只需要修改这个行为即可。(例如事务处理、日志管理、权限控制)封装起来,减少系统的重复代码,降低代码之间的耦合度,并有利于未来的可扩展性和可维护性。
OOP是面向对象编程,核心思想是将客观存在的不同事物抽象成相互独立的类,然后把与事物相关的属性和行为封装到类里,并通过继承和多态来定义类彼此间的关系,最后通过操作类的实例来完成实际业务逻辑的功能需求。
OOP与AOP的区别:
1、面向目标不同:简单来说OOP是面向名词领域,AOP面向动词领域。
2、思想结构不同:OOP是纵向结构,AOP是横向结构。
3、注重方面不同:OOP注重业务逻辑单元的划分,AOP偏重业务处理过程的某个步骤或阶段。
package com.ym.blog.api.annotation;
import java.lang.annotation.*;
/**
* 日志注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {
String module() default "";
String operation() default "";
}
在需要使用切面的地方,注解即可。
package com.ym.blog.api.aop;
import com.alibaba.fastjson.JSON;
import com.ym.blog.api.annotation.LogAnnotation;
import com.ym.blog.api.utils.HttpContextUtil;
import com.ym.blog.api.utils.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* @Author: Yangmiao
* @Date: 2022/9/13 20:58
* @Desc: 日志切面
*/
@Aspect
@Component
@Slf4j
public class LogAspect {
@Pointcut("@annotation(com.ym.blog.api.annotation.LogAnnotation)")
public void logPointCut(){
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
long startTime = System.currentTimeMillis();
Object proceed = proceedingJoinPoint.proceed();
long time = System.currentTimeMillis()-startTime;
recordLog(time,proceedingJoinPoint);
return proceed;
}
private void recordLog(long time, ProceedingJoinPoint joinPoint) {
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
log.info("=====================log start================================");
log.info("module:{}",logAnnotation.module());
log.info("operation:{}",logAnnotation.operation());
// 请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
log.info("request method:{}",className + "." + methodName + "()");
// 请求的参数
Object[] args = joinPoint.getArgs();
String params = JSON.toJSONString(args[0]);
log.info("params: {}",params);
// 请求的ip
log.info("ip address: {}", IpUtils.getIpAddr(HttpContextUtil.getHttpServletRequest()));
log.info("excute time : {} ms",time);
log.info("=====================log end================================");
}
}
欢迎大家关注个人微信公众号:一杯Java不加糖呢,不定期更新文章,谢谢🙏~
