Spring系列第22篇:@Scope、(1),Java岗

看一下其源码:

@Target({ElementType.TYPE, ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface Scope {

@AliasFor(“scopeName”)

String value() default “”;

@AliasFor(“value”)

String scopeName() default “”;

ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;

}

@Scope可以用在类上和方法上

参数:value和scopeName效果一样,用来指定bean作用域名称,如:singleton、prototype

常见2种用法

  1. 和@Compontent一起使用在类上

  2. 和@Bean一起标注在方法上

案例1:和@Compontent一起使用在类上

@Component

@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)//@1

public class ServiceA {

}

上面定义了一个bean,作用域为单例的。

@1:ConfigurableBeanFactory接口中定义了几个作用域相关的常量,可以直接拿来使用,如:

String SCOPE_SINGLETON = “singleton”;

String SCOPE_PROTOTYPE = “prototype”;

案例2:和@Bean一起标注在方法上

@Bean标注在方法上,可以通过这个方法来向spring容器中注册一个bean,在此方法上加上@Scope可以指定这个bean的作用域,如:

@Configurable

public class MainConfig2 {

@Bean

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

public ServiceA serviceA() {

return new ServiceA();

}

}

@DependsOn:指定当前bean依赖的bean


用法

前面有篇文章中介绍了bean xml中depend-on的使用,建议先看一下:Spring系列第9篇:depend-on到底是干什么的?

@DependsOn等效于bean xml中的bean元素中的depend-on属性。

spring在创建bean的时候,如果bean之间没有依赖关系,那么spring容器很难保证bean实例创建的顺序,如果想确保容器在创建某些bean之前,需要先创建好一些其他的bean,可以通过@DependsOn来实现,@DependsOn可以指定当前bean依赖的bean,通过这个可以确保@DependsOn指定的bean在当前bean创建之前先创建好

看一下其源码:

@Target({ElementType.TYPE, ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface DependsOn {

String[] value() default {};

}

可以用在任意类型和方法上。

value:string类型的数组,用来指定当前bean需要依赖的bean名称,可以确保当前容器在创建被@DependsOn标注的bean之前,先将value指定的多个bean先创建好。

常见2种用法

  1. 和@Compontent一起使用在类上

  2. 和@Bean一起标注在方法上

案例1:和@Compontent一起使用在类上

下面定义3个bean:service1、service2、service3;service1需要依赖于其他2个service,需要确保容器在创建service1之前需要先将其他2个bean先创建好。

看代码:

Service2

package com.javacode2018.lesson001.demo27.test3;

import org.springframework.stereotype.Component;

@Component

public class Service2 {

public Service2() {

System.out.println(“create Service2”);

}

}

Service3

package com.javacode2018.lesson001.demo27.test3;

import org.springframework.stereotype.Component;

@Component

public class Service3 {

public Service3() {

System.out.println(“create Service3”);

}

}

Service1

package com.javacode2018.lesson001.demo27.test3;

import org.springframework.context.annotation.DependsOn;

import org.springframework.stereotype.Component;

@DependsOn({“service2”, “service3”}) //@1

@Component

public class Service1 {

public Service1() {

System.out.println(“create Service1”);

}

}

@1:使用了@DependsOn,指定了2个bean:service2和service3,那么spring容器在创建上面这个service1的时候会先将@DependsOn中指定的2个bean先创建好

来个配置类

package com.javacode2018.lesson001.demo27.test3;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan

public class MainConfig3 {

}

测试用例

@Test

public void test3() {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig3.class);

System.out.println(context.getBean(Service1.class));

}

运行输出

create Service2

create Service3

create Service1

com.javacode2018.lesson001.demo27.test3.Service1@9f116cc

从输出中可以看到,spring容器在创建service1之前,先将service2和service3创建好了。

案例2:和@Bean一起标注在方法上

下面通过配置文件的方式来创建bean,如下:

package com.javacode2018.lesson001.demo27.test4;

import org.springframework.beans.factory.annotation.Configurable;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.DependsOn;

@Configurable

public class MainConfig4 {

@Bean

@DependsOn({“service2”, “service3”})//@1

public Service1 service1() {

return new Service1();

}

@Bean

public Service2 service2() {

return new Service2();

}

@Bean

public Service3 service3() {

return new Service3();

}

}

上面是一个spring的配置类,类中3个方法定义了3个bean

@1:这个地方使用了@DependsOn,表示service1这个bean创建之前,会先创建好service2和service3

来个测试用例

@Test

public void test4() {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig4.class);

System.out.println(context.getBean(com.javacode2018.lesson001.demo27.test4.Service1.class));

}

运行输出

create Service2

create Service3

create Service1

com.javacode2018.lesson001.demo27.test4.Service1@6e20b53a

@ImportResource:配置类中导入bean定义的配置文件


用法

有些项目,前期可能采用xml的方式配置bean,后期可能想采用spring注解的方式来重构项目,但是有些老的模块可能还是xml的方式,spring为了方便在注解方式中兼容老的xml的方式,提供了@ImportResource注解来引入bean定义的配置文件。

bean定义配置文件:目前我们主要介绍了xml的方式,还有一种properties文件的方式,以后我们会介绍,此时我们还是以引入bean xml来做说明。

看一下这个注解的定义:

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)

@Documented

public @interface ImportResource {

@AliasFor(“locations”)

String[] value() default {};

@AliasFor(“value”)

String[] locations() default {};

Class<? extends BeanDefinitionReader> reader() default BeanDefinitionReader.class;

}

通常将其用在配置类上。

有3个参数:

  • value和locations效果一样,只能配置其中一个,是一个string类型的数组,用来指定需要导入的配置文件的路径。
  • reader:用来指定bean定义的读取器,目前我们知道的配置bean的方式有xml文件的方式,注解的方式,其实还有其他的方式,比如properties文件的方式,如果用其他的方式,你得告诉spring具体要用那种解析器去解析这个bean配置文件,这个解析器就是BeanDefinitionReader,以后我们讲BeanDefinition的时候再细说。

资源文件路径的写法

通常我们的项是采用maven来组织的,配置文件一般会放在resources目录,这个目录中的文件被编译之后会在target/classes目录中。

spring中资源文件路径最常用的有2种写法:

  1. 以classpath:开头:检索目标为当前项目的classes目录

  2. 以classpath*:开头:检索目标为当前项目的classes目录,以及项目中所有jar包中的目录,如果你确定jar不是检索目标,就不要用这种方式,由于需要扫描所有jar包,所以速度相对于第一种会慢一些

那我们再来说classpath:和classpath*:后面的部分,后面的部分是确定资源文件的位置地方,几种常见的如下:

相对路径的方式

classpath:com/javacode2018/lesson001/demo27/test5/beans.xml

或者

classpath*:com/javacode2018/lesson001/demo27/test5/beans.xml

/:绝对路径的方式

classpath:/com/javacode2018/lesson001/demo27/test5/beans.xml

*:文件通配符的方式

classpath:/com/javacode2018/lesson001/demo27/test5/beans-*.xml

会匹配test5目录中所有以beans-开头的xml结尾的文件

*:目录通配符的方式

classpath:/com/javacode2018/lesson001/demo27//beans-.xml

会匹配demo27中所有子目录中所有以beans-开头的xml结尾的文件,注意这个地方只包含demo27的子目录,不包含子目录的子目录,不会进行递归

**:递归任意子目录的方式

classpath:/com/javacode2018/**/beans-*.xml

**会递归当前目录以及下面任意级的子目录

ok,继续回到@ImportResource上来,来看案例

案例代码

来2个类,这两个类我们分别用2个xml来定义bean

ServiceA

package com.javacode2018.lesson001.demo27.test5;

public class ServiceA {

}

ServiceB

package com.javacode2018.lesson001.demo27.test5;

public class ServiceB {

}

beans1.xml来定义serviceA这个bean,如下

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns=“http://www.springframework.org/schema/beans”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">

beans2.xml来定义serviceB这个bean,如下

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns=“http://www.springframework.org/schema/beans”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">

下面来个配置类,来引入上面2个配置文件

package com.javacode2018.lesson001.demo27.test5;

import org.springframework.beans.factory.annotation.Configurable;

import org.springframework.context.annotation.ImportResource;

@Configurable

@ImportResource(“classpath:/com/javacode2018/lesson001/demo27/test5/beans*.xml”)

public class MainConfig5 {

}

这个类上使用了@Configurable表示这是个配置类

并且使用了@ImportResource注解来导入上面2个配置文件

来个测试用例加载上面这个配置类

@Test

public void test5() {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig5.class);

for (String beanName : context.getBeanDefinitionNames()) {

System.out.println(String.format(“%s->%s”, beanName, context.getBean(beanName)));

}

}

上面会输出MainConfig5配置类中所有定义的bean

运行输出

mainConfig5->com.javacode2018.lesson001.demo27.test5.MainConfig5@4ec4f3a0

serviceA->com.javacode2018.lesson001.demo27.test5.ServiceA@223191a6

serviceB->com.javacode2018.lesson001.demo27.test5.ServiceB@49139829

从输出中可以看出2个xml中定义的bean也被注册了

@Lazy:延迟初始化


自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

最后

针对以上面试题,小编已经把面试题+答案整理好了

最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo

最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo

最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo

面试专题

image

除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习

image

image

image
单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-oGP4YAlK-1711997365768)]
[外链图片转存中…(img-9ZXqnLz4-1711997365769)]
[外链图片转存中…(img-NdacyQ8P-1711997365769)]
[外链图片转存中…(img-4q4yYCBi-1711997365770)]
[外链图片转存中…(img-wyJ1epDe-1711997365770)]
[外链图片转存中…(img-Cms84OEd-1711997365771)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-xLgQnDM4-1711997365771)]

最后

针对以上面试题,小编已经把面试题+答案整理好了

[外链图片转存中…(img-3pipspuK-1711997365771)]

[外链图片转存中…(img-FIblAxm6-1711997365771)]

[外链图片转存中…(img-0ORJ0g7m-1711997365772)]

面试专题

[外链图片转存中…(img-1CuD7Sgk-1711997365772)]

除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习

[外链图片转存中…(img-uHTA6UHB-1711997365772)]

[外链图片转存中…(img-jB1awR2o-1711997365772)]

[外链图片转存中…(img-PkIHzYoA-1711997365773)]

  • 26
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值