Bean

  1. 配置一个 bean 的时候,我们可以不设置 id,也可以不设置 name,spring 默认会使用类的全限定名作为 bean 的标识符
  2. 如果使用 id 属性来设置 bean 的标识符,那么 id 在 spring 容器中必需唯一
  3. 如果同时设置 id 和 name,那么 id 设置的是标识符,name 设置的是别名
  4. 如果 id 和 name 的值相同,那么 spring 容器会自动检测并消除冲突:让这个 bean 只有标识符,而没有别名
  5. name 属性设置多个值。不设置 id,那么第一个被用作标识符,其他的被视为别名。如果设置了 id,那么 name 的所有值都是别名
  6. 使用 标签指定别名,别名也必须在 IoC 容器中唯一

PostConstruct

Constructor (构造方法) -> @Autowired (依赖注入) -> @PostConstruct (注释的方法)

应用:在静态方法中调用依赖注入的 Bean 中的方法

properties 配置读取

file.properties

1
fileupload.rootpath=/Users/mac126/work

方式一:通过 context:property-placeholder 加载配置文件

  1. spring.xml

    1
    2
    3
    4
    <context:property-placeholder location="classpath:file.properties" ignore-unresolvable="true" />

    <!-- 自动扫描类所在包(自动注入) - java 中引入前必须经过扫描 -->
    <context:component-scan base-package="com.bjtcrj.gms.core.utils" />
  2. 在 spring.xml 中引用

    1
    2
    <!-- 基本属性-->
    <property name="rootpath" value="${fileupload.rootpath}" />
  3. Java 中引用

    • 普通成员变量引用

      1
      2
      3
      4
      5
      @Component
      public class FileGenerator {
      @Value("${fileupload.rootpath}")
      private String rootpath;
      }
    • 静态变量引用

      • 方法一

        1
        2
        3
        4
        5
        6
        7
        8
        9
        @Component
        public class FileGenerator {
        public static String ROOTPATH;

        @Value("${fileupload.rootpath}")
        public void setRootpath(String rootpath) {
        ROOTPATH = rootpath;
        }
        }
      • 方法二

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      @Component
      public class FileGenerator {
      public static String ROOTPATH;

      @Value("${fileupload.rootpath}")
      private String rootpath;

      @PostConstruct
      public void init() {
      ROOTPATH = rootpath;
      }
      }

方式二:@PropertySource 注解实现配置文件加载

  1. 在 java 类文件中使用 PropertySource 注解

    1
    2
    3
    4
    5
    6
    7
    @Component
    @Data
    @PropertySource(value={"classpath:file.properties"})
    public class FileuploadProperties {
    @Value(value="${fileupload.rootpath}")
    private String rootpath;
    }
  2. 在 java 文件中使用

    1
    2
    @Autowired
    private FileuploadProperties fileuploadProperties;

new 出来的对象不能自动注入对象问题

1. 新建一个工具类,比如 SpringContextUtil

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package com.bjtcrj.gms.common.utils;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component //注意此时要加注解
public class SpringContextUtil implements ApplicationContextAware {

private static ApplicationContext applicationContext; // Spring应用上下文环境

/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
*
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}

/**
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}

/**
* 获取对象
*
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws BeansException
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}

/**
* 获取类型为requiredType的对象 如果bean不能被类型转换,相应的异常将会被抛出(BeanNotOfRequiredTypeException)
*
* @param name
* bean注册名
* @param requiredType
* 返回对象类型
* @return Object 返回requiredType类型对象
* @throws BeansException
*/
public static Object getBean(String name, Class requiredType) throws BeansException {
return applicationContext.getBean(name, requiredType);
}

/**
* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
*
* @param name
* @return boolean
*/
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}

/**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
*
* @param name
* @return boolean
* @throws NoSuchBeanDefinitionException
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return applicationContext.isSingleton(name);
}

/**
* @param name
* @return Class 注册对象的类型
* @throws NoSuchBeanDefinitionException
*/
public static Class getType(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getType(name);
}

/**
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
*
* @param name
* @return
* @throws NoSuchBeanDefinitionException
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getAliases(name);
}
}

2. 使用

1
private OtherClass otherClass = (OtherClass)SpringContextUtil.getBean("otherClass");

DataSourceUtils

根据数据源获取数据库 schema

1
String schema = DataSourceUtils.getConnection(datasource).getCatalog();

注意

  1. 不要重复扫描包

问题

java.lang.NoClassDefFoundError: org/springframework/beans/factory/ObjectProvider

解决:从 Spring 4.3 版本以后才有这个类,可以提高版本