The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform.
属性赋值@value赋值 使用@Value赋值
基本数值
可以写SPEL表达式 #{}
可以${}获取配置文件信息(在运行的环境变量中的值)
使用xml时候导入配置文件是
<context:property-placeholder location ="classpath:person.properties" />
使用注解可以在配置类添加一个@PropertySource注解把配置文件中k/v保存到运行的环境中
使用${key}来获取
@PropertySource(value = {"classpath:/person.properties"}) @Configuration public class MainConfigOfPropertyValue { @Bean public Person person () { return new Person(); } }
Person 类
@Data public class Person { @Value("vhuj") private String name; @Value("#{20-2}") private Integer age; @Value("${person.nickName}") private String nickName; }
测试
@Test public void test01 () { printBean(applicationContext); System.out.println("---------------------------" ); Person person = (Person) applicationContext.getBean("person" ); System.out.println(person); System.out.println("---------------------------" ); }
输出
--------------------------- Person(name=vhuj, age=18, nickName=三三) ---------------------------
自动装配@Autowired@Qualifier@Primary 自动转配:
Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值
@Autowired自动注入:
a. 默认优先按照类型去容器中寻找对应的组件,如果找到去赋值
b. 如果找到到相同类型的组件,再将属性名(BookDao bookdao
)作为组件的id去容器中查找
c. 接下来还可以使用@Qualifier("bookdao")
明确指定需要装配的id
d. 默认是必须的,我们可以指定 @Autowired(required=false)
,指定非必须
@Primary让Spring自动装配时首先装配
自动装配@Resource和@Inject Spring还支持使用@Resource (JSR250) 和@Inject (JSR330) 注解,这两个是java规范
@Resource和@Autowired一样实现自动装配功能,默认是按组件名称进行装配的
没有支持@Primary和@Autowird(required=false)的功能
自动装配其他地方的自动装配 @Autowired:构造器、参数、方法属性等
标注到方法位子上@Bean+方法参数,参数从容器中获取
public class Boss { @Autowired private Car car; @Autowired public Boss (@Autowired Car car) { } public Car getCar () { return car; } @Autowired public void setCar (@Autowired Car car) { this .car = car; } }
自动装配Aware注入Spring底层注解 自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory 等等),自定义组件实现xxxAware,在创建对象的时候会调用接口规定的方法注入相关的组件
public interface Aware {}
我们实现几个常见的Aware接口
@Component public class Red implements BeanNameAware ,BeanFactoryAware , ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setBeanName (String name) { System.out.println("当前Bean的名字: " + name); } @Override public void setBeanFactory (BeanFactory beanFactory) throws BeansException { System.out.println("当前的BeanFactory: " + beanFactory); } @Override public void setApplicationContext (ApplicationContext applicationContext) throws BeansException { this .applicationContext = applicationContext; System.out.println("传入的ioc: " + applicationContext); } }
注入到配置中测试
public class IOCTestAware { @Test public void test01 () { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAware.class); } }
测试结果
当前Bean的名字: red 当前的BeanFactory: org.springframework.beans.factory.support.DefaultListableBeanFactory@159c4b8: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,mainConfigOfAware,red]; root of factory hierarchy 传入的ioc: org.springframework.context.annotation.AnnotationConfigApplicationContext@1e89d68: startup date [Tue Sep 25 10:29:17 CST 2018]; root of context hierarchy
把Spring自定义组件注入到容器中
原理:
public interface ApplicationContextAware extends Aware {}
通过 Debug 方式,定位到 org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization
@Override public Object postProcessBeforeInitialization (final Object bean, String beanName) throws BeansException { AccessControlContext acc = null ; if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) { acc = this .applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null ) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run () { invokeAwareInterfaces(bean); return null ; } }, acc); } else { invokeAwareInterfaces(bean); }
调用下面方法进行判断,每种 xxxAware 接口中只有一种方法,并调用相应的方法
private void invokeAwareInterfaces (Object bean) { if (bean instanceof Aware) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware) bean).setEnvironment(this .applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this .embeddedValueResolver); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) bean).setResourceLoader(this .applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this .applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware) bean).setMessageSource(this .applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(this .applicationContext); } } }
xxxAware
都是通过xxxProcessor
来处理的
比如:ApplicationContextAware
对应 ApplicationContextAwareProcessor
自动装配@Profile环境搭建 Profile是Spring为我们提供可以根据当前环境,动态的激活和切换一系组件的功能
a. 使用命令动态参数激活:虚拟机参数位子加载 -Dspring.profiles.active=test
b. 使用代码激活环境
我们想配置类
@Configuration public class MainConfigOfProfile { @Profile(value = "test") @Bean(value = "testDataSource") public DataSource testDataSource () { System.out.println("testDataSource" ); return null ; } @Profile(value = "dev") @Bean(value = "devDataSource") public DataSource devDataSource () { System.out.println("devDataSource" ); return null ; } }
测试
public class IOCTestProfile { @Test public void test01 () { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.getEnvironment().setActiveProfiles("test" ); applicationContext.register(MainConfigOfProfile.class); applicationContext.refresh(); } }
输出