Spring 注解、IOC(注解方式)、DI(注解的方式)

一、注解、IOC(注解方式)、DI(注解的方式)

1、注解的概念

注释:给人看的提示信息,程序不看也不执行。
注解:主要给程序看的信息,程序会执行。
通常用来在某种程度上,尤其是框架上,注解用来代替配置文件,实现轻量级配置。
注解是从JDK5.0开始提供的特性。

2、几个常见的注解

(1)@Override 子类继承父类,重写父类方法的注解
(2)@Deprecated 过时注解
(3)@SuppressWarnings 消除黄色警告

3、自定义注解

自定义一个注解的过程类似于定义一个接口
可以通过@interface来定义一个注解
该注解可以在一个类中的任何地方使用
元注解:可以通过元注解来修饰注解,控制自定义注解的特征(元注解都是sun公司提供好的)

(1)@Target – 声明当前定义的注解可以用在什么位置

ElementType.CONSTRUCTOR 构造方法中
ElementType.FIELD 成员变量
ElementType.LOCAL_VARIABLE 局部变量上
ElementType.METHOD 方法上
ElementType.PACKAGE 包
ElementType.PARAMETER 方法参数
ElementType.TYPE 类

(2)@Retention 了解即可,偏底层设计

声明当前定义的注解被保留到什么阶段
A.java源文件 —> A.class字节码文件 —>JVM
编译 运行

RetentionPolicy.SOURCE 保留到源码阶段,在编译过程中丢失,主要是给编译器在编译代码的时候看到。
RetentionPolicy.CLASS 保留到.java和…class阶段,加载到jvm虚拟机,运行时就丢失了。
RetentionPolicy.RUNTIME 全阶段

(3)@Documented 文档注解

指定当前注解是否会被文档提取工具提取到自动生成的文档中

(4)注解中声明属性

  • 1)在注解中声明属性的过程类似于接口中定义方法;
  • 2)在注解声明中定义的属性需要在使用注解时为属性赋值(相当于接口中的方法必须重写,注解中的属性必须赋值);
  • 3)在注解中声明的属性必须是public,public可以省略;
  • 4)在注解中声明的属性的类型必须是八大基本数据类型,String类型、Class类型,枚举类型(enum),其它注解类型,或者以上类型的一维数组。
  • 5)在给注解中的属性赋值时,可以在使用注解的后面使用小括号,小括号里采用属性名=赋值内容的方式赋值,多个值之间用逗号分隔开。
  • 6)可以在注解中声明属性时,使用default给属性赋一个默认值
  • 7)如果注解中只有一个属性需要被赋值,且该属性的名字叫value,则在赋值的时候value=是可以省略的
  • 8)如果注解中某个属性是一个一维数组类型,且给该属性赋值时,赋值的内容只有一个值,则赋值时大括号是可以省略的。
  • 如果赋值的内容是多个值,则赋值的内容必须放在大括号里

4、注解的反射:基于注解实现控制程序执行

RetentionPolicy.RUNTIME级别的注解会保留到程序运行时,可以通过反射技术获取,从而根据是否有注解或注解属性值的不同控制程序按照不同方式进行。

 boolean isAnnotationPresent()     判断是否有注解
 getAnnotation()                 获得注解

5、Spring注解方式实现IOC

Spring除了默认的使用xml配置文件的方式实现之外,也支持使用注解的方式来实现配置,注解的方式效率更高,配置信息更清晰,修改更方便,推荐使用。
前期准备工作:
(1)需要导入一个新的jar包 spring-aop…jar包
(2)引入context约束文件

案例:使用配置文件的方式和注解的方式分别配置javabean类
配置文件的方式配置javabean类的步骤:
(1)在applicationContext.xml文件中配置

注解的方式配置javabean类步骤:
(1)在applicationContext.xml文件中开启全包扫描

(2)在javabean类上添加注解@Component
在使用@Component注解时,id的推断规则:
(1)如果明确指定了id的值,则使用指定的id值
(2)如果没有明确指定id的值,则自动推断id的值:
自动推断id时,看类名的第二个字母
如果类名的第二个字母是小写,则首字母转小写组成id的值;
如果类名的第二个字母是大写,则首字母保持不变组成id的值。

6、Spring注解方式实现工厂模式(实例工厂)

  • (1)对实例工厂加@Component注解
  • (2)对实例工厂中的方法添加@Bean注解

7、Spring注解方式实现静态工厂模式

  • (1)对静态工厂加注解@Component注解
  • (2)对静态方法添加@Bean注解
    Spring框架 IOC(配置文件的方式、注解的方式)
    DI(配置文件的方式、注解的方式)

8、Spring注解方式实现DI(依赖注入)

  • (1)注解实现DI—常规属性 String int double… @Value
    Hero.java文件
  • (2)注解实现DI–@Value注解读取properties文件中的内容
    @Value(${xxx})
    MySQLConnection.java文件
  • (3)注解实现DI—集合和Properties对象
    数据写在applicationContext.xml文件中,用util约束
    使用@Value(#{@id值})获取数据给属性赋值
    Person.java文件
  • (4)一个javabean类包含另外一个javabean类的情况
    使用注解@Autowired来完成自动装配

自动装配的实现原理:
会先按照类型进行匹配,如果找到唯一的类型就进行依赖注入;
如果找不到类型会报错误;
如果找到的为多个类型,则再开始按照id进行查找;如果找到唯一的id就实现依赖注入,如果找不到报错误。

正常情况:
代码运行没有任何异常错误

@Autowired
private Dog dog;
先按照类型(Dog类型)找到了3个,Dog类,HSQDog和JMDog,按照类型找是不唯一的;
再按照id查找匹配,根据属性dog匹配id的值,能找到唯一的Dog类
测试1:去掉Dog类上的@Component,运行程序,报错误
先按照Dog类型查找,找到2个,分别是HSQDog和JMDog,按照类型找是不唯一的
再按照id查找,根据属性dog匹配id的值,因为HSQDog和JMDog的默认id都不是dog,所以id没有匹配到
所以程序运行报错误了
测试2:去掉Dog类上的@Component,再去掉HSQDog类上的@Component,运行正常。
先按照Dog类型查找,只查找到了一个,JMDog,按照类型能够找到唯一的。
测试3:HSQDog,JMDog这两个类加@Component,Dog类还是去掉@Component,同时给HSQDog手动的添加id的值为dog。
先按照Dog类型查找,找到了2个,HSDQdog和JMDog,按照类型找到的是不唯一的;
然后再按照id查找,因为HSQDog的id设置的就是dog,根据属性dog就能找到id的dog。
运行正常 使用@Qualifier注解配置@Autowired注解一起使用 自动装配时不再按照类型匹配查找了,直接按照@Qualifier定义的内容直接进行id匹配查找

9、其它注解(单例,多例,懒加载,spring容器的初始化和销毁)

@Scope 设置单例、多例的注解
@Scope(value=”prototype”) 多例
@Scope(“singleton”) 单例
@Lazy 懒加载注解
@PostConstruct Spring容器初始化的时候执行注解的方法
@PreDestory Spring容器销毁的时候执行注解的方法

10、案例—软件开发分层、彻底解耦合

@Controller @Service @Repository @Component
这四个注解的功能是完全相同的,都是用来修饰类的,会将类修饰为Spring容器管理的javabean对象。
其中@Component一般认为是通用注解
@Controller一般用在软件分层中的控制层,一般用在web层
@Service一般用在软件分层中的业务访问层,一般用在service层
@Repository一般用在软件分层中的数据访问层,一般用在dao层
Model模型层 View视图层 Controller控制层

JaveEE的经典三层架构

Spring 注解、IOC(注解方式)、DI(注解的方式)_第1张图片

在JavaEE的经典三层架构中,将Model模型层的功能进一步细分,JavaBean只负责数据的封装,Service负责业务逻辑处理,Dao负责数据库的访问。

你可能感兴趣的:(Java开源框架,Spring)