diff --git a/Java基础教程/Java学习路线.md b/Java基础教程/Java学习路线.md index f990ec61..f25a04e7 100644 --- a/Java基础教程/Java学习路线.md +++ b/Java基础教程/Java学习路线.md @@ -16,12 +16,13 @@ * [ ] maven教程 * [ ] idea教程 * [ ] Java框架教程(Spring全家桶,白天自学) - * [ ] Spring + * [ ] Spring5:20221010 * [ ] Springboot * [ ] Spring MVC * [ ] SpringCloud * [ ] Java云计算和微服务 - * [ ] docker + * [x] shell(bash&awk):20220926 + * [ ] docker:20221003 * [ ] k8s * [ ] servicemesh * [ ] Java性能优化 @@ -43,4 +44,4 @@ * [ ] redis * [ ] mybatis * [ ] 消息中间件 - * [ ] kfk消息队列 \ No newline at end of file + * [ ] kfk消息队列 diff --git a/Spring/Spring5/00 概述.md b/Spring/Spring5/00 概述.md index 23bdeab9..cbe767f8 100644 --- a/Spring/Spring5/00 概述.md +++ b/Spring/Spring5/00 概述.md @@ -30,6 +30,7 @@ * Aop:面向切面,不修改源代码的情况下,进行功能的增强。 + ## 2 入门实例 1. 创建普通java工程。 @@ -77,4 +78,27 @@ public class Test01 { } } -``` \ No newline at end of file +``` +## 3 架构 + +### 架构说明 + +![](image/2022-10-09-11-43-24.png) + +* 起核心内容包括四个jar包,引入即可使用spring最基础的功能。所以说它是一个轻量级的框架。(总共大概有20个jar包) +## 包的两个作用 + + +> 包的两种作用 +> * 水平分层——层次。位于不同的层次,应该在包的某个字段体现出来。service层、view层、dao层等。 +> * 垂直分割——功能。同一个功能在不同层次有不同力度的对应和实现,应该在包类的某个字段体现出来。包括book功能,sell功能等。 +> 一个包类路径的命名(功能结构或者说项目架构),应该是水平分层和垂直分割方法的交替。 + +## 导入jar包的方法 + +1. 如果是普通的java工程,需要手动下载jar包。 + 1. 去mvn仓库,搜索jar包,点击jar下载。 + 2. 然后再工程中添加该jar包(idea以来搜索路径) + +2. 如果是maven工程,直接引入pom即可 + 1. maven会自动管理并下载jar包。 \ No newline at end of file diff --git a/Spring/Spring5/01 1IOC容器原理.md b/Spring/Spring5/01 1IOC容器原理.md new file mode 100644 index 00000000..9bb43503 --- /dev/null +++ b/Spring/Spring5/01 1IOC容器原理.md @@ -0,0 +1,115 @@ +## 1 IOC容器原理 +### IOC概念 +* 控制反转。把对象创建和对象调用的过程,交给Spring进行管理。 +* 使用IOC的目的:降低代码耦合度。 + + +### 底层原理 + + +* xml解析 +* 工厂模式 +* 反射 + + +1. java对象调用的过程 + +![](image/2022-10-08-11-53-59.png) +```java +class UserDao{ + add(){ + + } +} +public class UserService{ + public void execute(){ + UserDao dao = new UserDao(); + dao.add(); + } +} +``` +2. 使用工厂模式 +![](image/2022-10-08-11-54-46.png) +```java +class UserDao{ + add(){ + + } +} +class UserFactory{ + public static UserDao getDao(){ + return new UserDao(); + } +} + +class UserService{ + execute(){ + UserDao dao = UserFactory.getDao(); + dao.add(); + } +} +``` + +3. IOC模式实现。通过xml解析、工厂模式、反射,进一步降低耦合度。 + 1. 创建xml配置文件 + 2. 创建工厂类,解析xml,使用IOC机制创建对象。 + 3. 降低耦合度,不依赖java对象,而是通过配置文件决定具体实例化的对象。根据id查找class.forName(className),加载字节码文件,通过Instance方法,实例化对象。值依赖一个ClassName的字符串。可以随时更改,而不用依赖具体的包名、对象名和对象中的构造方法。 + +![](image/2022-10-08-12-04-49.png) + +```xml + +``` +```java +class UserDao{ + add(){ + + } +} +class UserFactory{ + public static UserDao getDao(){ + String classValue = class属性值;//XML解析 + Class classzz = Class.forName(classValue)//通过反射创建对象。 + return (UserDao)clazz.newInstance(); + } +} + +class UserService{ + execute(){ + UserDao dao = UserFactory.getDao(); + dao.add(); + } +} +``` +## 2 IOC接口BeanFactory&ApplicationContext + +IOC思想是基于IOC容器完成的,IOC容器底层就是对象工厂(工厂通过xml文件解析类名,通过反射机制创建对象实例)。 + +### 实现方法 +Spring提供了IOC容器实现的两种方式。耗时耗资源的操作,尽量在初始化的时候完成,所以ApplicationContext这个接口更常使用。 + +* BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供给开发人员使用。 + * 加载配置文件的时候,不会创建对象。在获取(使用)对象的时候,才去创建对象。 +* ApplicationContext。BeanFactory接口的子接口,提供了更多更强大的功能,一般由开发人员进行使用。 + * 加载配置文件的时候就会把配置文件对象进行创建。 + +* BeanFactory +继承结构如下,有多种子接口和实现方法 +![](image/2022-10-08-14-18-55.png) + +* ApplicationContext + +继承结构如下 +![](image/2022-10-08-14-11-22.png) + +* FileSystemXmlApplicationContext,存储盘下的xml路径 +* ClassPathXmlApplicationContext,是src下的类路径 + +### IOC操作Bean的步骤和方式 +主要包括两个步骤 +* Spring创建对象——依赖倒置 +* Spring注入属性——依赖注入 + +主要两种方式 +* 基于XML的方式 +* 基于注解的方式 \ No newline at end of file diff --git a/Spring/Spring5/01 IOC Container.md b/Spring/Spring5/01 2IOC基于XML容器管理.md similarity index 57% rename from Spring/Spring5/01 IOC Container.md rename to Spring/Spring5/01 2IOC基于XML容器管理.md index 533c5db5..90d6d3bf 100644 --- a/Spring/Spring5/01 IOC Container.md +++ b/Spring/Spring5/01 2IOC基于XML容器管理.md @@ -1,120 +1,6 @@ -## 1 IOC容器原理 -### IOC概念 -* 控制反转。把对象创建和对象调用的过程,交给Spring进行管理。 -* 使用IOC的目的:降低代码耦合度。 +# IOCBean管理基于XML方式 - -### 底层原理 - - -* xml解析 -* 工厂模式 -* 反射 - - -1. java对象调用的过程 -![](image/2022-10-08-11-53-59.png) -```java -class UserDao{ - add(){ - - } -} -public class UserService{ - public void execute(){ - UserDao dao = new UserDao(); - dao.add(); - } -} -``` -2. 使用工厂模式 -![](image/2022-10-08-11-54-46.png) -```java -class UserDao{ - add(){ - - } -} -class UserFactory{ - public static UserDao getDao(){ - return new UserDao(); - } -} - -class UserService{ - execute(){ - UserDao dao = UserFactory.getDao(); - dao.add(); - } -} -``` - -3. IOC模式实现。通过xml解析、工厂模式、反射,进一步降低耦合度。 - 1. 创建xml配置文件 - 2. 创建工厂类,解析xml,使用IOC机制创建对象。 - 3. 降低耦合度,不依赖java对象,而是通过配置文件决定具体实例化的对象。根据id查找class.forName(className),加载字节码文件,通过Instance方法,实例化对象。值依赖一个ClassName的字符串。可以随时更改,而不用依赖具体的包名、对象名和对象中的构造方法。 - -![](image/2022-10-08-12-04-49.png) - -```xml - -``` -```java -class UserDao{ - add(){ - - } -} -class UserFactory{ - public static UserDao getDao(){ - String classValue = class属性值;//XML解析 - Class classzz = Class.forName(classValue)//通过反射创建对象。 - return (UserDao)clazz.newInstance(); - } -} - -class UserService{ - execute(){ - UserDao dao = UserFactory.getDao(); - dao.add(); - } -} -``` -## 2 IOC接口BeanFactory&ApplicationContext - -IOC思想是基于IOC容器完成的,IOC容器底层就是对象工厂(工厂通过xml文件解析类名,通过反射机制创建对象实例)。 - -### 实现方法 -Spring提供了IOC容器实现的两种方式。耗时耗资源的操作,尽量在初始化的时候完成,所以ApplicationContext这个接口更常使用。 - -* BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供给开发人员使用。 - * 加载配置文件的时候,不会创建对象。在获取(使用)对象的时候,才去创建对象。 -* ApplicationContext。BeanFactory接口的子接口,提供了更多更强大的功能,一般由开发人员进行使用。 - * 加载配置文件的时候就会把配置文件对象进行创建。 - -### BeanFactory -继承结构如下,有多种子接口和实现方法 -![](image/2022-10-08-14-18-55.png) - -### ApplicationContext - -继承结构如下 -![](image/2022-10-08-14-11-22.png) - -* FileSystemXmlApplicationContext,存储盘下的xml路径 -* ClassPathXmlApplicationContext,是src下的类路径 - -### IOC操作Bean - -* Spring创建对象——依赖倒置 -* Spring注入属性——依赖注入 - -主要两种方式 -* 基于XML的方式 -* 基于注解的方式 -## 3 IOCBean管理基于XML方式 - -### 基于XMl方式创建对象 +## 1 基于XMl方式创建对象 ```xml id:对象唯一标识 @@ -123,13 +9,13 @@ name:对象名称标识 ``` * 在Spring给你配置文件中,使用bean标签,标签里添加对应属性。实现对象的创建 * bean中有很多属性 -* 创建对象的时候,执行午餐构造函数。 +* 创建对象的时候,执行无参构造函数。 -### 基于XML方式注入属性 +## 2 基于XML方式注入属性 > DI依赖注入,就是注入属性。 -* 原始的属性注入方法 +### 原始的属性注入方法 ```java @@ -171,11 +57,10 @@ public class Book { } ``` - -* 第一种方法:使用set方法进行注入. - * 创建属性和属性对应的set方法。 - * 在Spring配置文件配置对象创建和属性注入。 - * 加载配置文件获取指定的对象。 +### 第一种方法:使用set方法进行注入. +* 创建属性和属性对应的set方法。 +* 在Spring配置文件配置对象创建和属性注入。 +* 加载配置文件获取指定的对象。 ```xml @@ -209,8 +94,8 @@ public class Book { } ``` -* 第二种方法:使用有参构造函数进行注入 - * 创建类和属性,创建对应属性的有参构造方法。 +### 第二种方法:使用有参构造函数进行注入 +* 创建类和属性,创建对应属性的有参构造方法。 ```java /** * Alipay.com Inc. @@ -528,7 +413,8 @@ public class Student { ``` -### 普通bean和工厂bean +## 3 普通bean和工厂bean +Spring中有两种类型的bean: * 普通bean:在配置文件中定义的Bean类型就是返回类型 * 工厂bean:在配置文件中定义的Bean类型和返回类型可以不一样。 @@ -537,15 +423,231 @@ public class Student { * 创建类,让这个类作为工厂bean。实现接口factoryBean * 实现接口里面的方法,在实现的方法中定义返回bean类型。 +```java + +public class MyBean implements FactoryBean { + + //定义返回bea + @Override + public Course getObject() throws Exception { + Course course = new Course(); + return course; + } + + @Override + public Class getObjectType() { + return null; + } + + @Override + public boolean isSingleton() { + return FactoryBean.super.isSingleton(); + } +} + + @Test + public void testFactoryBean(){ + ApplicationContext context = new ClassPathXmlApplicationContext("bean03.xml"); + Course myBean = context.getBean("mybean", Course.class); + System.out.println(myBean); + } +``` +```xml + +``` + +## 4 Bean的作用域 +* 在Spring里可以设置Bean是单实例还是多实例。 +* 在Spring里,默认情况下是,bean是单实例对象。 +![](image/2022-10-09-09-48-50.png) + +* 在spring文件bean标签里面的属性scope用于设置是单实例还是多实例。 + * scope=singleton,表示单实例对象。 + * scope=prototype,表示多实例对象。 + +```xml + + +``` +* singleton在加载配置文件的时候,就会创建单实例对象。饿汉式。 +* prototype在调用getBean方法的时候,才会创建对象。懒汉式。 + +> 这个跟之前记录的BeanFactory和ApplicationContext的区别有点像。不如就说BeanFactory默认scope为prototype,ApplicationContext默认scope为singleton。 + +* scope还有一下两个值。表示不同的作用域。 + * request + * seesion + +## 5 Bean的生命周期 +### 基本步骤 +从对象创建到对象销毁的过程。包括五个最基本的步骤。 + +1. 通过构造器创建bean实例。 +2. 为bean的属性设置值和对其他bean的引用(调用set方法) +3. 调用bean中初始化的方法(需要进行配置) +4. bean可以使用了 +5. 当容器关闭的时候,调用bean的销毁方法(需要进行配置) + +```java +public class Order { + private String oname; + + public Order(String oname) { + this.oname = oname; + } + + public Order() { + System.out.println("第一步 执行无参构造函数创建bean实例"); + } + public void setOname(String oname) { + this.oname = oname; + System.out.println("第二步 调用set方法设置属性值"); + } + + public String getOname() { + return oname; + } + + public void initMethod(){ + System.out.println("第三部 调用初始化方法"); + } + + public void destroyMethod(){ + System.out.println("第五步 调用销毁方法"); + } + +} + @Test + public void testCollection(){ + ApplicationContext context = new ClassPathXmlApplicationContext("bean05.xml"); + Order order = context.getBean("order", Order.class); + System.out.println("第四步 获取bean实例对象"); + ((ClassPathXmlApplicationContext)context).close(); + } +``` + +```xml + + + +``` -## 4 IOCBean管理基于注解方式 +### Post处理器步骤 +添加后置处理器后,总共有7步 +1. 通过构造器创建bean实例。 +2. 为bean的属性设置值和对其他bean的引用(调用set方法) +3. 把bean实例传递bean后置处理器的方法 +4. 调用bean中初始化的方法(需要进行配置) +5. 把bean实例传递Bean后置处理器的方法 +6. bean可以使用了 +7. 当容器关闭的时候,调用bean的销毁方法(需要进行配置) -> 包的两种作用 -> * 水平分层——层次。位于不同的层次,应该在包的某个字段体现出来。service层、view层、dao层等。 -> * 垂直分割——功能。同一个功能在不同层次有不同力度的对应和实现,应该在包类的某个字段体现出来。包括book功能,sell功能等。 -> 一个包类路径的命名(功能结构或者说项目架构),应该是水平分层和垂直分割方法的交替。 \ No newline at end of file + +实例:后置处理器的效果演示 + +创建类,实现接口BeanPostProcessor,创建后置处理器 + + +```java +public class MyBeanPost implements BeanPostProcessor { + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + System.out.println("后置处理器,前置任务");; + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + System.out.println("后置处理器,后置任务"); + return bean; + } +} +``` + +```xml + + + + + + +``` + +## 6 自动装配 + +1. 手动装配:通过property的那么和value属性。 +2. 自动装配:根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入。 + +* bean标签autowire实现自动装配。autowire通常包含连个值 + * byName根据属性名称注入(bean的id和属性名称一致) + * byType根据属性类型注入(如果该类型有多个实例会出错) + +```xml + + + + +``` + + +## 7 外部属性文件 + +### 直接配置数据信息 + +```xml + + + + + + +``` + + +### 引入外部属性文件配置数据库连接池 + +1. 编辑外部属性文件.properties +2. 引入外部属性文件,添加新的命名空间context + +``` +prop.driverClass=com.mysql.jdbc.Driver +prop.url=jdbc:mysql://localhost:3306/user +prop.username=root +prop.password=123456 +``` + +```xml + + + + + + + + + + + + + + + + + + + + + +``` \ No newline at end of file diff --git a/Spring/Spring5/01 3IOC基于注解容器管理.md b/Spring/Spring5/01 3IOC基于注解容器管理.md new file mode 100644 index 00000000..1f7647bd --- /dev/null +++ b/Spring/Spring5/01 3IOC基于注解容器管理.md @@ -0,0 +1,180 @@ +# IOCBean管理基于注解方式 +# 基于注解方式IOCBean管理 + +## 1 简介 + +### 注解概念 + +* 注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值) +* 注解的位置:注解可以作用在类、属性、方法。 +* 使用目的:简化XML配置 + +### IOC的两个步骤 + +* 创建对象 +* 注入属性 +## 2 基于注解方式创建对象 + +### 实现创建对象的注解 +四个注解功能是一样的,都可以用来创建bean实例。 + +* @Component 组件层 +* @Service service层 +* @Controller web层 +* @Repository DO层 + +### 使用注解创建对象bean的步骤 +1. 引入依赖。spring-aop(该jar包实现了注解) +2. 开启组件扫描(context命名空间,添加扫描) + 1. 检测到组件扫描,会扫描包下的所有类。 + 2. 可以通过filters过滤 + +```xml + + + + + + + +``` +3. 在类上添加注解,创建对象的bean + +```java +/** + * 与xml配置等价,value值可以省略不写 + * 默认值是类名称,首字母小写。 + */ +@Component(value="userService") +public class UserService { + public void add(){ + System.out.println("service add ......"); + } +} +``` + +### context扫描设置 + +* 使用自己配置的filter。use-default-filter="false + * context:include-filter只扫描指定注解 + * context:exclude-filter不扫描指定注解 + +```xml + + + + + + + +``` + +## 3 基于注解方式实现属性注入 + + +### 实现属性注入的注解 + +* @Autowired:根据属性类型进行自动装配 +* @Qualifier:根据属性名称进行注入 +* @Resource:可以根据属性类型、属性名称进行注入 +* @Value:注入普通类型的属性 + +### @Autowire基于注解的属性注入步骤 + +1. 在service和dao对象类上添加创建对象的注解。 +2. 在service中注入dao对象,在Service类中添加dao类型属性,在属性上使用注解。 + + +``` +@Service +public class UserService { + + @Autowired + private UserDo userDo; + public void add(){ + System.out.println("service add ... ..."); + + userDo.add(); + } +} + +@Repository +public class UserDoImpl implements UserDo{ + @Override + public void add() { + System.out.println("dao add ... ..."); + } +} +``` + +### @Qualifier根据名称进行注入 + + +* 必须跟Autowire配合使用。因为根据类型注入存在歧义的时候,使用名称进行区分(id) + +``` + @Autowired + @Qualifier(value = "userDoImpl") + private UserDo userDo; + public void add(){ + System.out.println("service add ... ..."); + + userDo.add(); + } +``` + +### @Resource属性注入 +> Resource是javax扩展包中的注解 +* 默认值为根据类型进行注入 +* 根据名称进行注入,使用name属性 + +```java +@Resource + +@Resource(name="service") +``` + + +### @Value注入普通属性 + +```java + @Value("abc") + pirvate String name; +``` + + +## 4 完全注解开发 +> 可以不用xml配置文件。 +### 相关注解 + +* @Configuration +* @ComponentScan + +### 完全注解开发流程 + +* 创建配置类,代替xml配置文件。 +``` +@Configuration +@ComponentScan(basePackages = {"com.ykl"}) +public class SpringConfig { + +} +``` + +* 编写测试类 + +``` + @Test + public void testConfig(){ + //加载配置类 + ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); + UserService userService = context.getBean("userService", UserService.class); + userService.add(); + } +``` \ No newline at end of file diff --git a/Spring/Spring5/02 AOP.md b/Spring/Spring5/02 AOP.md index de9dd5c6..28db7cdd 100644 --- a/Spring/Spring5/02 AOP.md +++ b/Spring/Spring5/02 AOP.md @@ -1,9 +1,344 @@ ## 1 AOP基本概念 +### 概念 +面向切面编程Aspect Oriented Programming +* 通过 预编译方式 和 运行期间动态代理 实现程序功能的统一维护的一种技术。 +* AOP是OOP(面相对象编程)的延续。是函数式编程的一种衍生泛型。 +* 利用AOP可以对业务逻辑的各个部分进行隔离。降低耦合度、提高可用性、提高开发效率 +### 主要功能 +将日志记录、性能统计、安全控制、事务处理、异常处理等代码从业务逻辑代码中划分出来。 + +通俗描述:不通过修改源代码的方法,在主干功能里添加新功能 + +![](image/2022-10-09-14-04-57.png) ## 2 AOP底层原理 +### 动态代理的原理 +AOP使用动态代理实现面向切面编程 + +* 有接口情况,使用JDK动态代理 + * 设计模式:代理模式。创建接口实现类代理对象,增强类的方法。 + +![](image/2022-10-09-14-10-44.png) + + +* 没有接口情况,使用CGLIB实现动态代理 + * 创建子类继承原来的类。 + * 创建当前类子类的代理对象,增强类中的方法。 + +![](image/2022-10-09-14-13-52.png) + + +### 动态代理的实现 + +1. JDK 动态代理的实现。使用java.lang.reflect.Proxy,通过反射原理实现动态代理。 + 1. 第一个参数:类加载器 + 2. 第二个参数:被代理的接口 + 3. 第三个参数:增强方法的逻辑,实现接口 + +```java +static Object newProxyInstance(ClassLoader loader, 类[] interfaces, InvocationHandler h) +返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序 +``` +2. 编写JDK动态代理的代码 + +```java +package com.ykl.dao; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * @author yinkanglong + * @version : JDKProxy, v 0.1 2022-10-09 14:31 yinkanglong Exp $ + */ +public class JDKProxy { + public static void main(String[] args) { + Class[] interfaces = {UserDo.class}; + +// Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new InvocationHandler() { +// @Override +// public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { +// return null; +// } +// }); + + UserDoImpl userDo = new UserDoImpl(); + UserDo dao = (UserDo)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),interfaces,new UserDaoProxy(userDo)); + int result = dao.add(1,2); + System.out.println("结束"); + } +} +class UserDaoProxy implements InvocationHandler{ + Object object; + //把被代理的对象,传递进来。通过有参构造进行传递 + public UserDaoProxy(Object object){ + this.object=object; + } + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + System.out.println("方法之前的执行"+method.getName()); + + Object res = method.invoke(object,args); + + System.out.println("方法执行后"); + + return res; + } +} +``` + + +## 3 术语 + +### 连接点 +* 类中可以被增强的方法称为连接点 + +### 切入点 +* 实际被真正增强的方法称为切入点 +### 通知(增强) +实际增强的逻辑部分称为通知 + +通知的多种类型 +* 前置通知Before。 +* 后置通知AfterReturn。正常返回才有 +* 环绕通知Around。通过切入点修改前后 +* 异常通知afterThrowing +* 最终通知after。finally无论出现异常都执行。 + +### 切面 +切面是一个工作。 +把通知应用到切入点的过程,就叫做切面。 + + +## 4 AOP操作 + +### AspectJ +在Spring框架中一般基于AspectJ实现AOP操作 + +AspectJ不是Spring的组成部分,独立AOP框架,一般把AspectJ和Spring框架一起使用,进行AOP操作。 + +基于AspectJ实现AOP操作有两种方式 +* 基于XML配置文件实现 +* 基于注解方式实现 + +### 在项目中引入相关的依赖 + +![](image/2022-10-09-15-08-27.png) + +### 切入点表达式 +作用:知道要对哪个类、哪个方法进行增强。 + +语法结构 +```java +execution([权限修饰符][返回类型][类全路径名][方法名称]([参数列表])) + +对com.ykl.UserDao里的add方法进行增强 +execution(* com.ykl.dao.UserDao.add(..) +对类中所有的方法进行增强 +execution(* com.ykl.dao.UserDao.*(..) +对包中所有类所有方法进行增强 +execution(* com.ykl.dao.*.*(..) +``` + +## 5 基于AspectJ注解AOP + +### 使用步骤 +1. 创建类,在类中定义方法 +```java +@Component +public class User { + public void add(){ + System.out.println("User add ..."); + } +} +``` +2. 创建增强类(编写增强逻辑) + 1. 在增强类里创建方法,不同的方法代表不同的名字。 +```java +@Component +@Aspect +public class UserProxy { + + //前置通知 + public void before(){ + System.out.println("执行前..."); + } +} +``` +3. 进行通知的配置 + 1. 在spring的配置文件中,开启注解扫描 + 2. 使用注解创建User和UserProxy对象 + 3. 在增强类上添加注解@Aspect + 4. 在spring配置文件中开启生成代理对象 + +```xml + + + + + + + + +``` + +4. 配置不同类型的通知 + 1. 在增强类里面,在作为通知的方法上面,添加通知类型的注解。并通过切入点表达式配置。 + +```java +/** + * Alipay.com Inc. + * Copyright (c) 2004-2022 All Rights Reserved. + */ +package com.ykl.aopanno; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.*; +import org.springframework.stereotype.Component; + +/** + * @author yinkanglong + * @version : UserProxy, v 0.1 2022-10-09 15:16 yinkanglong Exp $ + */ +@Component +@Aspect +public class UserProxy { + + //前置通知 + @Before(value = "execution(* com.ykl.aopanno.User.add(..))") + public void before(){ + System.out.println("执行前..."); + } + + //最终通知,有异常也执行 + @After(value = "execution(* com.ykl.aopanno.User.add(..))") + public void after(){ + System.out.println("after..."); + } + + //抛出异常后不执行 + @AfterReturning(value = "execution(* com.ykl.aopanno.User.add(..))") + public void afterReturn(){ + System.out.println("afterReturn..."); + } + + @AfterThrowing(value = "execution(* com.ykl.aopanno.User.add(..))") + public void afterThrow(){ + System.out.println("afterThrow..."); + } + + //通过切入点设置了环绕前后 + @Around(value = "execution(* com.ykl.aopanno.User.add(..))") + public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{ + System.out.println("环绕之前...."); + + proceedingJoinPoint.proceed(); + + System.out.println("环绕之后...."); + } + +} +``` + +正常的执行顺序如下 + +![](image/2022-10-09-15-40-14.png) + +当抛出异常的时候执行顺序如下 + +![](image/2022-10-09-15-39-59.png) + + +### @Pointcut公共切入点抽取 +由于很多操作都具有相同的切入点,配置相同。所以可以抽取相同的切入点 + + +```java +@Pointcut(value = "execution(* com.ykl.aopanno.User.add(..))") +public void point(){ + +} + +//前置通知 +@Before(value = "point()") +public void before(){ + System.out.println("执行前..."); +} +``` + +### @Order增强类的优先级 + +有多个增强类对同一个方法进行增强,设置增强类的优先级。 + +* 在增强类上面添加注解@Order(数字类型的值),数字类型值越小优先级越高。 + +```java +@Component +@Aspect +@Order(1) +public class PersonProxy { + +} +``` + +### 完全注解开发 + +通过配置类代替XML的注解 + + +``` +@Configuration +@ComponentScan(basePackages={"com.ykl"}) +@EnableAspectJAutoProxy(proxyTargetClass=true) +public class ConfigAop{ + +} +``` + +## 6 基于AspectJ配置文件 + +1. 创建两个类,增强类和被增强类,创建方法 +2. 在spring配置文件中创建两个类对象 +3. 在spring配置文件中配置切入点 + +```xml + + + + + + + + + + + + + + + + + + +``` + -## 3 AOP操作 \ No newline at end of file diff --git a/Spring/Spring5/03 ORM Data JDBC.md b/Spring/Spring5/03 JDBCTemplate.md similarity index 100% rename from Spring/Spring5/03 ORM Data JDBC.md rename to Spring/Spring5/03 JDBCTemplate.md diff --git a/Spring/Spring5/image/2022-10-09-09-48-50.png b/Spring/Spring5/image/2022-10-09-09-48-50.png new file mode 100644 index 00000000..64fcc79f Binary files /dev/null and b/Spring/Spring5/image/2022-10-09-09-48-50.png differ diff --git a/Spring/Spring5/image/2022-10-09-11-43-24.png b/Spring/Spring5/image/2022-10-09-11-43-24.png new file mode 100644 index 00000000..ac16eaf7 Binary files /dev/null and b/Spring/Spring5/image/2022-10-09-11-43-24.png differ diff --git a/Spring/Spring5/image/2022-10-09-14-04-57.png b/Spring/Spring5/image/2022-10-09-14-04-57.png new file mode 100644 index 00000000..12070de8 Binary files /dev/null and b/Spring/Spring5/image/2022-10-09-14-04-57.png differ diff --git a/Spring/Spring5/image/2022-10-09-14-10-44.png b/Spring/Spring5/image/2022-10-09-14-10-44.png new file mode 100644 index 00000000..ac44644d Binary files /dev/null and b/Spring/Spring5/image/2022-10-09-14-10-44.png differ diff --git a/Spring/Spring5/image/2022-10-09-14-13-52.png b/Spring/Spring5/image/2022-10-09-14-13-52.png new file mode 100644 index 00000000..2a5c4ada Binary files /dev/null and b/Spring/Spring5/image/2022-10-09-14-13-52.png differ diff --git a/Spring/Spring5/image/2022-10-09-15-08-27.png b/Spring/Spring5/image/2022-10-09-15-08-27.png new file mode 100644 index 00000000..fe969ed6 Binary files /dev/null and b/Spring/Spring5/image/2022-10-09-15-08-27.png differ diff --git a/Spring/Spring5/image/2022-10-09-15-39-59.png b/Spring/Spring5/image/2022-10-09-15-39-59.png new file mode 100644 index 00000000..25306d0e Binary files /dev/null and b/Spring/Spring5/image/2022-10-09-15-39-59.png differ diff --git a/Spring/Spring5/image/2022-10-09-15-40-14.png b/Spring/Spring5/image/2022-10-09-15-40-14.png new file mode 100644 index 00000000..07a4c4fd Binary files /dev/null and b/Spring/Spring5/image/2022-10-09-15-40-14.png differ diff --git a/start.sh b/start.sh new file mode 100644 index 00000000..a954dd00 --- /dev/null +++ b/start.sh @@ -0,0 +1 @@ +git push -f git@github.com:Estom/notes.git