Spring中的自动配置

Spring中的自动配置

1.区别管理和不管理的类

通过注解方式(想要管理的加上注解)

  • @Controller 控制器。 用于描述 web层的处理器。
  • @Service : 用于描述 服务层的对象。
  • @Repository : 用于描述 Dao层的对象。
  • @Component : 一般性的组件
    以上注解对Spring管理,效果上没有任何差别,但是使用时最好根据语义来。

2.类之间的依赖关系

  • 使用Spring提供的标准注解 @Autowired
  • 使用Java标准的 @Resource
  • 使用Java标准的 @Inject (需要额外导入jar包)

3.开启自动配置的功能

  • 跟注解有关的功能 ,导入 Spring 的 aop 模块
    • 下载地址:
      链接:https://pan.baidu.com/s/1G3ro61zrEyDdjFzRBc8bSg
      提取码:vbkr
  • 在配置文件中使用 <context:component-scan> 来开启扫描

4.Bean配置案例

目录结构
在这里插入图片描述

在Spring 的xml中开启扫描

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
    
    //传入要扫描的路径
    <context:component-scan base-package="com.example.spring"></context:component-scan>
</beans>

测试类

public class Demo1 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "com/example/spring/scan/spring-config.xml");
        String[] beanDefinitionNames  = context.getBeanDefinitionNames();

        for (int i = 0; i <beanDefinitionNames.length ; i++) {
            System.out.println(beanDefinitionNames[i]);
        }
    }
}

4.1 Spring 自己的Bean

只要开启扫描后Spring 就会自动创建一些自己的Bean,结果如下:
在这里插入图片描述

4.2 自定义Bean

创建自己的Bean类

@Component
public class TestBean1 {
}

测试结果:
在这里插入图片描述
打印结果是类名首字母小写

4.3自定义修改Bean在容器中的名字

如果想要自定义Bean的名字可以在注解上进行传入

@Component(value = "aaa")
public class TestBean1 {
}

显示结果:
在这里插入图片描述

4.4 自定义Bean的scope属性

使用@Scpoe()注解

  • singleton表示单例对象,
  • prototype表示每创建一次都创建一个新的
@Scope("singleton")
@Component(value = "aaa")
public class TestBean1 {
}

测试

public class Demo1 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "com/example/spring/scan/spring-config.xml");

        TestBean1 aaa1 = (TestBean1) context.getBean("aaa");
        TestBean1 aaa2 = (TestBean1) context.getBean("aaa");
        System.out.println(aaa1==aaa2);

    }
}

显示结果:
在这里插入图片描述

4.5 指定生命周期方法

标签:

  • @PostContruct
  • @PreDestory

测试代码:
这里需要注意的是ApplicationContext 没有close方法,没办法正常关闭容器,只能使用子类ConfigurableApplicationContext

public class Demo1 {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
                "com/example/spring/scan/spring-config.xml");
                
        TestBean1 aaa = (TestBean1) context.getBean("aaa");
        context.close();

    }
}

Bean代码:
Bean类Scope只能是单例,如果是prototype则容器关闭时不会执行end()方法

@Scope("singleton")
@Component(value = "aaa")
public class TestBean1 {

    @PostConstruct
    public void start(){
        System.out.println("初始化方法");
    }
    @PreDestroy
    public void end(){
        System.out.println("销毁方法");
    }

}

显示结果:
在这里插入图片描述
调整Scope为prototype显示结果:
在这里插入图片描述

5.简单依赖注入

简单属性注入
在这里插入图片描述
将外部配置文件的属性值注入
out-source.properties文件

string=sss

Bean

@Scope("singleton")
@Component(value = "aaa")
public class TestBean1 {
	//指定外部文件属性值的名称
    @Value("${string}")
    private String string;

    @PostConstruct
    public void start(){
        System.out.println("初始化方法");
    }
    @PreDestroy
    public void end(){
    	//打印拿到的外部文件属性值
        System.out.println(string);
        System.out.println("销毁方法");
    }

}

xml文件配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.example.spring"></context:component-scan>
    //指定要获取外部文件的路径
    <context:property-placeholder location="com/example/spring/scan/out-source.properties"></context:property-placeholder>
</beans>

显示结果:
在这里插入图片描述
@Value标签内也支持SpEL表达式

@Scope("singleton")
@Component(value = "aaa")
public class TestBean1 {
	//SpEL表达式
    @Value("#{'ssss'.substring(2)}")
    private String string;

    @PostConstruct
    public void start(){
        System.out.println("初始化方法");
    }
    @PreDestroy
    public void end(){
        System.out.println(string);
        System.out.println("销毁方法");
    }

}

显示结果:
在这里插入图片描述

6.其他Bean的注入

  • 使用Spring提供的注解@AutoWired
  • 使用java标准的@Resource
    创建一个新Bean
@Component
public class TestBean2 {
}

想要在TestBean1中作为成员变量引入有三种方式:

  1. 直接在变量声明时加注解
@Autowired  //或者@Resource
private TestBean2 testBean2;
  1. 在setter方法上加注解
    @Autowired  //或者@Resource
    public void setTestBean2(TestBean2 testBean2) {
        this.testBean2 = testBean2;
    }
  1. 在构造方法上加注解
    只能使用 @Autowired不能使用@Resource
    @Autowired
    public TestBean1(TestBean2 testBean2) {
        this.testBean2=testBean2;
    }

TestBean1代码:

@Scope("singleton")
@Component(value = "aaa")
public class TestBean1 {

    @Autowired
    private TestBean2 testBean2;

//   @Autowired
//    public TestBean1(TestBean2 testBean2) {
//        this.testBean2=testBean2;
//    }

//    @Autowired
//    public void setTestBean2(TestBean2 testBean2) {
//        this.testBean2 = testBean2;
//    }

    @Value("#{'ssss'.substring(2)}")
    private String string;

    @PostConstruct
    public void start(){
        System.out.println("初始化方法");
    }
    @PreDestroy
    public void end(){
		//在销毁前判定是否为空,不为空则表明注入成功
        System.out.println(testBean2!=null);
        System.out.println("销毁方法");
    }
}

Demo1测试

public class Demo1 {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
                "com/example/spring/scan/spring-config.xml");
        String[] beanDefinitionNames  = context.getBeanDefinitionNames();

        for (int i = 0; i <beanDefinitionNames.length ; i++) {
            System.out.println(beanDefinitionNames[i]);
        }

        TestBean1 aaa = (TestBean1) context.getBean("aaa");
        context.close();

    }
}

显示结果:

在这里插入图片描述

6.1 细节问题

  1. 当一个类中仅有一个带参数的构造方法是,参数类型会自动从Spring容器中获取
    即:上述使用@Autowired+构造方法的形式不使用@Autowired也是可以的
  2. 当有多个构造方法时,Spring容器会优先使用无参的构造方法,如果还想要进行自动注入,需要在想注入的构造方法上使用@Autowired
  3. 当有多个构造方法时,@Autowired注解只能标注在一个构造方法上
  4. 当容器中不存在想要注入的Bean时也会报错,也就是说想要自动注入的Bean肯定是已经被Spring管理了的
  5. 设定@Autowired(requeired = false),如果想要自动注入的Bean在Spring容器中不存在可以设定默认值为空,如果存在则使用容器中的Bean
  6. 如果想要自动注入的Bean在Spring容器中存在多于一个可能会报Bean不唯一的错误,并且想要注入的Bean在本类中存在的变量名与Spring容器中该Bean的name属性一致,也会影响Bean的注入
  7. 如果想要自动注入的Bean在Spring容器中存在多于一个,又想指定想要注入的Bean,则在该Bean上加注解@Primary或者在Spring配置的bean标签内加primary属性为true
  8. 如果不想修改配置和Bean,只想在变量声明上注释也是可以的,增加@Autowired+@Qualifier注解@Qualifier("想要注入的Bean的配置名称")或者直接使用@Resource(name="想要注入的Bean的配置名称")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值