基于SM的DI:

所谓注入,可以理解为对象的属性赋值

有两种方式: 设置注入构造注入

设置注入: (底层通过set方法给对象的属性赋值)

6.1.1 简单数据类型和引用数据类型注入

6.1.2 集合属性注入(array、set、list、map、properties)

6.1.3 域属性自动注入(byNamebyType;局部和全局配置)

6.1.4 空字符串或null的注入

6.1.1 简单数据类型和引用数据类型注入

首先创建两个实体类,然后在配置文件中注册两个bean,通过全限定名对应两个对象

那么后面便是对两个对象的属性赋值 -->通过property标签赋值




java 从静态文件读取 java静态织入_java 从静态文件读取


java 从静态文件读取 java静态织入_java 切面_02


java 从静态文件读取 java静态织入_java 动态添加注解_03


如果是引用类型的设置注入 需要在一个实体类中添加另个实体类对象,设置getset方法

一定要添加toString方法,否则获取不到值


java 从静态文件读取 java静态织入_java 动态添加注解_04


然后在配置文件中创建引用的属性值,引用属性值是ref


java 从静态文件读取 java静态织入_java 切面_05


测试结果


java 从静态文件读取 java静态织入_java 动态添加注解_06


6.1.2 集合属性注入(array、set、list、map、properties)

Bug1、 在这里遇到问题 主要是因为:实体类名字写错导致无法运行


java 从静态文件读取 java静态织入_java 从静态文件读取_07


所以在创建实体类时一定要注意不要写错:


java 从静态文件读取 java静态织入_java 动态添加注解_08


6.1.3 域属性自动注入(byNamebyType;局部和全局配置)

局部配置:

自动注入,不用再自己设置引用类型的注入

byName方式域属性自动注入:要求注入的bean的id必须和被注入的bean对象的属性名一致


java 从静态文件读取 java静态织入_java 从静态文件读取_09


java 从静态文件读取 java静态织入_java 实体类 临时注解_10


java 从静态文件读取 java静态织入_java 从静态文件读取_11


byType方式域属性自动注入:spring配置文件中查询与属性类型一致的bean并进行注入


java 从静态文件读取 java静态织入_java 动态添加注解_12


全局配置属性:


java 从静态文件读取 java静态织入_java 实体类 临时注解_13


6.1.4 空字符串或null的注入

给属性注入空字符串和null值的方法是通过value标签 和null标签来实现的


java 从静态文件读取 java静态织入_java 从静态文件读取_14


构造注入: (底层通过调用构造的方法,对象的属性赋值)

注意:

(1) 构造注入首先要在实体类中编写带参和无参的构造方法

  1. 构造注入不使用property标签,而是使用<constructor-arg>标签

构造注入有三种方式:

第一种是: 通过<constructor-arg>标签的name属性

第二种是: 通过<constructor-arg>标签的index属性获取参数下标

第三种是:直接通过value值直接获取,但是要求<constructor-arg>标签的参数值必须和构造器中的参数类型对应


java 从静态文件读取 java静态织入_java 动态添加注解_15


  1. 基于注解的DI

7.1环境搭建:导入aop包、添加context约束头信息(组件扫描器)

7.2常用注解:@Component、@Scope、@Value、@Resource、 @Autowired

@Component 表示当前类交给Spring容器管理

@Repository:该注解添加在Dao实现类上

@Service:该注解添加在Service实现类上

@Controller:该注解添加在Controller类上

@Scope: 使用作用域

@Value 简单数据类型通过@Value注入

基于注解方式的依赖注入,是不需要提供getset方法的,只需要加上组件注解即可

@Component 代表:当前类交给spring容器管理

简单数据类型的属性,直接通过@value赋值即可

引用数据类型的属性,通过域属性自动注入@AutoWired


java 从静态文件读取 java静态织入_java 动态添加注解_16


默认情况下是通过byType方式注入,如果使用byName方式注入,需要与@Qualifier联合使用


java 从静态文件读取 java静态织入_java 实体类 临时注解_17


java 从静态文件读取 java静态织入_java 切面_18


引用数据类型还可以通过@Resource也可以实现注入;是JDK提供的注解默,认情况下是byName方式注入,只有找不到与名称匹配的bean的时候才会按照类型来进行注入


java 从静态文件读取 java静态织入_java 动态添加注解_19


注意:它们两个之间的区别是:@Qualifier是通过spring提供的注解; @Resource是JDK提供的注解

与@Component具有相同功能的还有三个注解:


java 从静态文件读取 java静态织入_java 从静态文件读取_20


三、Spring之AOP

1. Aop引入

1.1 什么是代理?

1.2 为什么使用代理?

下面看一个示意图


java 从静态文件读取 java静态织入_java 从静态文件读取_21


1.3 代理分类:代理分为静态代理和动态代理

  1. 静态代理

若代理类在程序运行前就已经存在,那么这种代理方式被成为静态代理.这种情况下的代理类通常都是我们在Java代码中定义的。

通常情况下,静态代理中的代理类和目标类会实现同一接口或是派生自相同的父类.

代码示例: 通过对实现类中的方法进行增强,将返回值的China 变成大写的CHINA

实现步骤:

(1)首先定义一个代理类


java 从静态文件读取 java静态织入_java 切面_22


(2)编写一个实现目标对象值增强的方法,并创建一个目标对象target


java 从静态文件读取 java静态织入_java 从静态文件读取_23


  1. 静态代理要实现代理类和目标类相同的接口


java 从静态文件读取 java静态织入_java 切面_24


2.目标对象设置有参构造


java 从静态文件读取 java静态织入_java 动态添加注解_25


3.编写测试类进行测试


java 从静态文件读取 java静态织入_java 从静态文件读取_26


Bug1: 在代码测试期间出现问题:


java 从静态文件读取 java静态织入_java 动态添加注解_27


3. 动态代理 (下个知乎会有一个专门介绍动态代理的小总结知识点)

代理类在程序运行时创建的代理方式被成为动态代理.

也就是说,这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代 码中的“指示”动态生成的。

3.1 常用的动态代理有两类:JDK动态代理和CGLIB动态代理

JDK动态代理是JDK提供的机制,不需要导入额外的jar包

通过的是java.Lang.reflect包下提供的proxy类

Proxy.newProxyInstance(loader,interfaces,h)

Loader代表: 目标类的加载器

interfaces代表:目标类实现的接口

h代表:调用处理器

内部类调用外部修饰时需要添加final

3.2 两者应用场景:

3.2.1如果目标对象实现了接口,采用JDK的动态代理

3.2.2如果目标对象没有实现了接口,必须采用CGLIB动态代理

Aop介绍

面向切面编程,就是将交叉业务逻辑封装成切面,利用AOP的功能将切面织入到主 业务逻辑中。所谓交叉业务逻辑是指,通用的、与主业务逻辑无关的代码,如安全 检查、事务、日志等。

若不使用AOP,则会出现代码纠缠,即交叉业务逻辑与主业务逻辑混合在一起。这 样,会使主业务逻辑变的混杂不清。

4. Aop基本术语介绍

4.1 切面

切面泛指交叉业务逻辑。比如事务处理、日志处理就可以理解为切面。常用的切面 有通知与顾问。实际就是对主业务逻辑的一种增强。

4.2 织入

织入是指将切面代码插入到目标对象的过程。

4.3连接点

连接点指切面可以织入的位置。

4.4切入点

切入点指切面具体织入的位置。

5. Aop基本术语介绍

5.1 通知(Advice)

通知是切面的一种实现,可以完成简单织入功能(织入功能就是在这里完成的)。 通知定义了增强代码切入到目标代码的时间点,是目标方法执行之前执行,还是之 后执行等。通知类型不同,切入时间不同。

5.2 顾问(Advisor)

顾问是切面的另一种实现,能够将通知以更为复杂的方式织入到目标对象中,是将 通知包装为更复杂切面的装配器。 不仅指定了切入时间点,还可以指定具体的切入 点

6. AOP编程环境搭建

7. Spring对AOP的实现(基于Schema-based方式)

先学习 5.1 中常用通知分类

(这些通知实现步骤都一样,只是需要编写各自单独的java类下面前置通知进行详细步骤,其他同理.配置文件如下)


java 从静态文件读取 java静态织入_java 动态添加注解_28


(1)前置通知(MethodBeforeAdvice)

先编写一个前置通知(MethodBeforeAdvice)java类


java 从静态文件读取 java静态织入_java 实体类 临时注解_29


然后在配置文件中进行配置 要将切面放在代理当中


java 从静态文件读取 java静态织入_java 从静态文件读取_30


再编写测试类,运行


java 从静态文件读取 java静态织入_java 从静态文件读取_31


(2)后置通知(AfterReturningAdvice)


java 从静态文件读取 java静态织入_java 实体类 临时注解_32


java 从静态文件读取 java静态织入_java 切面_33


(3)环绕通知(MethodInterceptor)


java 从静态文件读取 java静态织入_java 切面_34


运行结果


java 从静态文件读取 java静态织入_java 动态添加注解_35


(4)异常处理通知(ThrowsAdvice)

注意:

这四个重载的方法并没有放在ThrowsAdvice接口中,选择第一个方法


java 从静态文件读取 java静态织入_java 从静态文件读取_36


java 从静态文件读取 java静态织入_java 切面_37


编写异常通知java类


java 从静态文件读取 java静态织入_java 动态添加注解_38


运行结果:


java 从静态文件读取 java静态织入_java 实体类 临时注解_39