Spring学习笔记-IOC(注解)

Spring注解开发

注解驱动的意义

什么是注解驱动?

注解驱动的好处

注解驱动的弊端

常用注解

(1)启动注解功能

(2)bean的定义

(3)bean的作用域

(4)bean的生命周期

(5)加载第三方资源

(6)bean的非引用类型属性注入

(7)bean的引用类型属性注入

(8)bean的引用类型属性注入(补充)

(9)加载properties文件

(10)纯注解格式

(11)第三方bean配置与管理

bean加载控制

(1)依赖加载

(2)依赖加载应用场景


Spring注解开发

注解驱动的意义

什么是注解驱动?

注解启动时使用注解的形式替代xml配置,将繁杂的spring配置文件从工程中彻底消除掉,简化书写

在XML中使用class属性指定bean是对应哪一个类的,id属性就是bean的名称;而在注解中就使用@Component("名称")

在XML中scope属性指定其范围,在注解中,就使用@Scope()

在XML中的init-methoddestroy-method,就相当于注解中的@PostConstruct@PerDestroy

注解驱动的好处

综上所述:使用注解开发,将会拥有更高的效率!大多数情况下可以使代码变得简便,更重要的是我们写代码的时候不需要在xml文件和Java类之间不断来回切换了。

注解驱动的弊端

  • 为了达成注解驱动的目的,可能会将原先很简单的书写,变的更加复杂

  • XML中配置第三方开发的资源是很方便的,但使用注解驱动无法在第三方开发的资源中进行编辑,因此会增大开发工作量

如下述所用阿里提供的Druid库时:

常用注解

(1)启动注解功能

启动注解扫描,加载类中配置的注解项

<context:component-scan base-package="packageName"/>

packageName就是你提供的包名。

说明:

  • 在进行对包的扫描时,会对配置的包其子包中所有文件进行扫描(所以配置的包越小越好!效率高)

  • 扫描过程是以文件夹递归迭代的形式进行的

  • 扫描过程仅读取合法的java文件

  • 扫描时仅读取spring可识别的注解

  • 扫描结束后会将可识别的有效注解转化为spring对应的资源加入IoC容器

注意:

  • 无论是注解格式还是XML配置格式,最终都是将资源加载到IoC容器中,差别仅仅是数据读取方式不同

  • 相比之下,在加载效率上来说,使用注解的方式要优于XML配置文件的方式。(注解写在哪,东西就在哪!不需要像之前使用XML的方式一样,要通过XML找Java中的类

(2)bean的定义

  • 名称:@Component @Controller @Service @Repository

@Controller、@Service 、@Repository是@Component的衍生注解,功能目前同@Component

Spring的野心很大,可能在未来只要使用上述注解就可以实现各个层级的职能!@Controller代表控制层,@Service代表业务层,@Repository代表数据层。但是目前还没有实现!

  • 类型:类注解

  • 位置:类定义上方

  • 作用:设置该类为spring管理的bean

样例:

@Component
public class ClassName{}

(3)bean的作用域

  • 名称:@Scope

  • 类型:类注解

  • 位置:类定义上方

  • 作用:设置该类作为bean对应的scope属性

样例:

@Component
public class ClassName{}

相关属性

  • value(默认):定义bean的作用域,默认为singleton

(4)bean的生命周期

  • 名称:@PostConstruct、@PreDestroy

  • 类型:方法注解

  • 位置:方法定义上方

  • 作用:设置该类作为bean对应的生命周期方法

样例:

@PostConstruct
public void init() { System.out.println("init..."); }
@PreDestroy
public void destroy() {}

(5)加载第三方资源

  • 名称:@Bean

  • 类型:方法注解

  • 位置:方法定义上方

  • 作用:设置该方法的返回值作为spring管理的bean

样例:

@Bean("dataSource")
public DruidDataSource createDataSource() {
    return ……;    
}
  • 说明:

    • 因为第三方bean无法在其源码上进行修改,使用@Bean解决第三方bean的引入问题

    • 该注解用于替代XML配置中的静态工厂与实例工厂创建bean,不区分方法是否为静态或非静态

    • @Bean所在的类必须被spring扫描加载,否则该注解无法生效

(6)bean的非引用类型属性注入

  • 名称:@Value

  • 类型:属性注解、方法注解

  • 位置:属性定义上方,方法定义上方

  • 作用:设置对应属性的值或对方法进行传参

样例:

@Value("注入的值")
private String username;
  • 说明:

    • value值仅支持非引用类型数据,赋值时对方法的所有参数全部赋值

    • value值支持读取properties文件中的属性值,通过类属性将properties中数据传入类中

    • value值支持SpEL

    • @value注解如果添加在属性上方,可以省略set方法(set方法的目的是为属性赋值)

问:这里为什么可以不适用set方法,而之前要?

之前是在XML文件中,由于属性声明是用private,私有的属性在别的类中访问不了!所以要使用set方法!

(7)bean的引用类型属性注入

  • 名称:@Autowired、@Qualifier

  • 类型:属性注解、方法注解

  • 位置:属性定义上方,方法定义上方

  • 作用:设置对应属性的对象或对方法进行引用类型传参

注意:

@Autowired默认按类型装配,当出现相同类型的bean,就按照id(变量名)装配!

使用@Primary提高按类型自动装配的优先级,多个@Primary会导致优先级设置无效

(8)bean的引用类型属性注入(补充)

  • 名称:@Inject、@Named、@Resource

  • 说明:

    • @Inject与@Named是JSR330规范中的注解,功能与@Autowired和@Qualifier完全相同,适用于不同架构场景

    • @Resource是JSR250规范中的注解,可以简化书写格式

  • @Resource相关属性

    • name:设置注入的bean的id

    • type:设置注入的bean的类型,接收的参数为Class类型

小结:

(9)加载properties文件

  • 名称:@PropertySource

  • 类型:类注解

  • 位置:类定义上方

  • 作用:加载properties文件中的属性值

样例:

@PropertySource(value = "classpath:文件名")
public class ClassName {
    @Value("文件中的变量名")
    private String attributeName;
}

不支持*通配格式,一旦加载,所有spring控制的bean中均可使用对应属性值

相关属性

  • value(默认):设置加载的properties文件名,value可以省略

  • ignoreResourceNotFound:如果资源未找到,是否忽略,默认为false

(10)纯注解格式

  • 名称:@Configuration、@ComponentScan

  • 类型:类注解

  • 位置:类定义上方

  • 作用:设置当前类为spring核心配置加载类

样例:

我们之前XML配置文件中还有一句话

<context:component-scan base-package="com.Harmony"/>

不过我们可以通过注解的方式将其也省略了!

新建一个名为SpringConfig的Java类

@Configuration
@ComponentScan("com.Harmony")
public class SpringConfig {

}

然后在UserApp类中使用反射的形式加载类

//ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

注: 

  • 核心配合类用于替换spring核心配置文件,此类可以设置空的,不设置变量与属性

  • bean扫描工作使用注解@ComponentScan替代

  • 加载纯注解格式上下文对象,需要使用AnnotationConfigApplicationContext

(11)第三方bean配置与管理

  • 名称:@Import

  • 类型:类注解

  • 位置:类定义上方

  • 作用:导入第三方bean作为spring控制的资源(在一个配置文件中,导入另一个配置文件)

@Configuration
@Import(OtherClassName.class)
public class ClassName {
}

注意:

  • @Import注解在同一个类上仅允许添加一次,如果需要导入多个,使用数组的形式进行设定

  • 在被导入的类中可以继续使用@Import导入其他资源(了解)

  • @Bean所在的类可以使用导入的形式进入spring容器,无需声明为bean

bean加载控制

(1)依赖加载

@DependsOn

  • 类型:注解、方法注解

  • 位置:bean定义的位置(类上或方法上)

  • 作用:控制bean的加载顺序,使其在指定bean加载完毕后再加载

  • 说明:

    • 配置在方法上,使@DependsOn指定的bean优先于@Bean配置的bean进行加载

    • 配置在上,使@DependsOn指定的bean优先于当前类中所有@Bean配置的bean进行加载

    • 配置在类上,使@DependsOn指定的bean优先于@Component等配置的bean进行加载

@Order

  • 类型:配置类注解

  • 位置:配置类定义的位置(类上)

  • 作用:控制配置类的加载顺序

@Order(1)
public class SpringConfig() {}

数值越小,越先加载! 

@Lazy

  • 名称:@Lazy

  • 类型:类注解、方法注解

  • 位置:bean定义的位置(类上或方法上)

  • 作用:控制bean的加载时机,使其延迟加载

(2)依赖加载应用场景

@DependsOn

  • 微信订阅号,发布消息和订阅消息的bean的加载顺序控制

  • 双11活动期间,零点前是结算策略A,零点后是结算策略B,策略B操作的数据为促销数据。策略B加载顺序与促销数据的加载顺序

@Lazy

  • 程序灾难出现后对应的应急预案处理是启动容器时加载时机

@Order

  • 多个种类的配置出现后,优先加载系统级的,然后加载业务级的,避免细粒度的加载控制

posted @ 2022-03-06 23:08  金鳞踏雨  阅读(24)  评论(0)    收藏  举报  来源