一.异常抛出增强、最终增强、环绕增强
1.异常增强
特点
1.在目标对象方法抛出异常时织入增强处理
2.可灵活拔插的异常处理方案
@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "exception")
public void handleException(Exception exception) {
// 处理异常的逻辑
System.out.println("Exception occurred: " + exception.getMessage());
2.最终增强
特点
1.无论方法正常运行还是抛出异常,都会在目标方法最后织入增强处理,即:该增强都会得到执行
2.与Java中finally代码块的作用相似,通常用于释放资源
3.可灵活拔插
/**
* 无论什么情况下都会执行的方法
*/
@After(value="execution(* com.mybatis.service..*.*(..))")
public void after(){
//方法的对象的关闭
//方法的回滚
System.out.println("最终通知....");
}
3.环绕增强
特点
1、目标方法前后都可织入增强处理
2、可获取或修改目标方法的参数、返回值
3、可对目标方法进行异常处理,甚至可以决定目标方法是否执行
/**
* 环绕通知
* @param joinPoint 可用于执行切点的类
* 具体什么业务
* @return
* @throws Throwable
*/
@Around("execution(* com.mybatis.service..*.*(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知前....");
Object obj= (Object) joinPoint.proceed();
System.out.println("环绕通知后....");
return obj;
}
二.p命名空间注入
使用属性而不是子元素的形式配置Bean的属性
语法:
<bean id="唯一标识" class="类的全路径"
p:"属性1"="注入的值" p:"属性2"="注入的值" />
<bean id="唯一标识" class="类的全路径"
p:属性-ref="注入的Bean" />
三.不同数据类型注入
四.使用注解实现Spring IoC
注解方式将Bean的定义信息和Bean实现类结合在一起,Spring提供的注解有
@Component:实现Bean组件的定义
@Repository:用于标注DAO类
@Service:用于标注业务类
@Controller:用于标注控制器类
1.首先添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.9</version> <!-- 或适用于你的版本 -->
</dependency>
2.启用组件扫描
<context:component-scan base-package="com.mybatis.mapper.impl,com.mybatis.service.impl"></context:component-scan>
3.标记目标类并依赖注入
五.使用注解实现Spring
1.AspectJ 面向切面的框架,它扩展了Java语言,定义了AOP语法,能够在编译期提供代码的织入
2.@AspectJ AspectJ 5新增的功能,使用JDK 5.0注解技术和正规的AspectJ切点表达式语言描述
3.切面 Spring通过集成AspectJ框架实现了以注解的方式定义切面,使得配置文件的代码大大减少
4.利用轻量级的字节码处理框架asm处理@AspectJ中所描述的方法参数名
实例:
Spring在同一个功能上提供了注解和配置文件两种实现方式以供选择 通常情况下,
优先选择注解来简化配置工作量
常用的注解
@AfterThrowing
@Before
@AfterReturning
@Around
@After
@Aspect
@Pointcut
六.反射原理
在理解反射的时候,不得不说一下内存。
先理解一下JVM的三个区:堆区,栈区,和方法去(静态区)。
堆区:存放所有的对象,每个对象都有一个与其对应的class信息。在JVM中只有一个堆区,堆区被所有的线程共享。
栈区:存放所有基础数据类型的对象和所有自定义对象的引用,每个线程包含一个栈区。每个栈区中的数据都是私有的,其他栈不能访问。
栈分为三部分:
基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
方法区:即静态区,被所有的线程共享。方法区包含所有的class和static变量。它们都是唯一的。
在启动一个java虚拟机时,虚拟机要加载你程序里所用到的类 ,这个进程会首先跑到jdk中(在jdk的jre/lib/ext文件夹里找那些jar文件),如果没有找到,会去classpath里设置的路径去找。
在找到要执行的类时:
1.首先将找到的类的信息加载到运行时数据区的方法区。这个过程叫做类的加载。所以一下static类型的在类的加载过程中就已经放到了方法区。所以不用实例化就能用一个static类型的方法。
2.加载完成后,在new一个类时,首先就是去方法区看看有没有这个类的信息。如果没有这个类的信息,先装载这个类。then,加载完成后,会在堆区为new的这个类分配内存,有了内存就有了实例,而这个实例指向的是方法区的该类信息。其实就是存放了在方法区的地址。而反射就是利用了这一点。