(Spring In Action)bean注入基础知识
2018-03-29 13:03
525 查看
Spring的使命:简化Java开发。
Spring为简化Java开发采取的4个关键策略:
①基于POJO的轻量级和最小侵入性编程;
②通过依赖注入和面向接口实现松耦合;
③通过切面和惯例进行声明式编程;
④通过切面和模板减少样板式代码;
Spring容器管理bean对象的生命周期和协作关系,Spring通过上下文对象将你对bean的配置加载进Spring容器,比如你在JavaConfig中配置,或者XML中,或者隐式配置(使用@Component等注解),这样容器就可以管理你的对象。
几种上下文对象:
① AnnotationConfigApplicationContext:从一个或多个基于java的配置类中加载上下文定义,适用于java注解的方式;@Configuration
② ClassPathXmlApplicationContext:从类路径下的一个或多个xml配置文件中加载上下文定义,适用于xml配置的方式;
③ FileSystemXmlApplicationContext:从文件系统下的一个或多个xml配置文件中加载上下文定义,也就是说系统盘符中加载xml配置文件;
④ AnnotationConfigWebApplicationContext:专门为web应用准备的,适用于注解方式;
⑤ XmlWebApplicationContext:从web应用下的一个或多个xml配置文件加载上下文定义,适用于xml配置方式。
bean的生命周期
JavaConfig
@Profile:多种环境下的不同bean
不同环境下的不同bean创建,每个profile代表一种环境,spring通过spring.profiles.active和spring.profiles.default属性来设置,如果active有设置值则是active,不然则是default设置的值,如果default也没有设置值,则@Profile定义的bean不会被创建。
有多种方式来设置这两个属性:
①作为DispatcherServlet的初始化参数;
②作为web应用的上下文参数;
③作为JNDI条目;
④作为环境变量;
⑤作为JVM的系统属性;
⑥在集成测试类上,使用@ActiveProfiles注解配置。
@Conditional满足条件才创建bean
@Conditional用到带有@bean注解的方法上,只有满足条件,才创建bean。
只有matches方法返回true,bean才会创建。
下面是一个例子:
Spring为简化Java开发采取的4个关键策略:
①基于POJO的轻量级和最小侵入性编程;
②通过依赖注入和面向接口实现松耦合;
③通过切面和惯例进行声明式编程;
④通过切面和模板减少样板式代码;
Spring容器管理bean对象的生命周期和协作关系,Spring通过上下文对象将你对bean的配置加载进Spring容器,比如你在JavaConfig中配置,或者XML中,或者隐式配置(使用@Component等注解),这样容器就可以管理你的对象。
几种上下文对象:
① AnnotationConfigApplicationContext:从一个或多个基于java的配置类中加载上下文定义,适用于java注解的方式;@Configuration
② ClassPathXmlApplicationContext:从类路径下的一个或多个xml配置文件中加载上下文定义,适用于xml配置的方式;
③ FileSystemXmlApplicationContext:从文件系统下的一个或多个xml配置文件中加载上下文定义,也就是说系统盘符中加载xml配置文件;
④ AnnotationConfigWebApplicationContext:专门为web应用准备的,适用于注解方式;
⑤ XmlWebApplicationContext:从web应用下的一个或多个xml配置文件加载上下文定义,适用于xml配置方式。
bean的生命周期
JavaConfig
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration //不指定值默认扫描自己所在的包以及子包 @ComponentScan public class CDPlayerConfig { }
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration //指定特定的包作为基础包 @ComponentScan(basePackages = {"com.Chapter2"}) public class CDPlayerConfig2 { }
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import com.Chapter2.CompactDisc; @Configuration //指定为特定的类和接口 @ComponentScan(basePackageClasses = {CompactDisc.class}) public class CDPlayerConfig3 { }
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.Chapter2.CDPlayer; import com.Chapter2.CompactDisc; import com.Chapter2.SgtPeppers; @Configuration //表明这个类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。 public class CDPlayerConfig4 { @Bean(name="lonelyHeartsClub") public CompactDisc sgtPeppers() { return new SgtPeppers(); } @Bean public CDPlayer cdPlayer() { return new CDPlayer(sgtPeppers()); } /*@Bean public CDPlayer cdPlayer(CompactDisc compactDisc) { //构造器注入 return new CDPlayer(compactDisc); }*/ @Bean public CDPlayer cdPlayer(CompactDisc compactDisc) { CDPlayer cdPlayer = new CDPlayer(compactDisc); //setter方法注入 cdPlayer.setCd(compactDisc); return cdPlayer; } }
@Profile:多种环境下的不同bean
不同环境下的不同bean创建,每个profile代表一种环境,spring通过spring.profiles.active和spring.profiles.default属性来设置,如果active有设置值则是active,不然则是default设置的值,如果default也没有设置值,则@Profile定义的bean不会被创建。
有多种方式来设置这两个属性:
①作为DispatcherServlet的初始化参数;
②作为web应用的上下文参数;
③作为JNDI条目;
④作为环境变量;
⑤作为JVM的系统属性;
⑥在集成测试类上,使用@ActiveProfiles注解配置。
public interface Person { public void speak(); } @Component @Profile("China") //Profile是China才会实例化这个bean public class Chinese implements Person { public void speak() { System.out.println("我说中文"); } } @Component @Profile("England") //Profile是England才会实例化这个bean public class English implements Person { public void speak() { System.out.println("I speak english"); } } @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=ProfileConfig.class) //集成测试类上,使用@ActiveProfiles注解设置 @ActiveProfiles({"England"/*,"China"*/}) public class ProfileTest { @Autowired Person p; @Test public void testProfile() { p.speak(); } } 输出:I speak english
@Conditional满足条件才创建bean
@Conditional用到带有@bean注解的方法上,只有满足条件,才创建bean。
只有matches方法返回true,bean才会创建。
@FunctionalInterface public interface Condition { /** * Determine if the condition matches. * @param context the condition context * @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class} * or {@link org.springframework.core.type.MethodMetadata method} being checked * @return {@code true} if the condition matches and the component can be registered, * or {@code false} to veto the annotated component's registration */ boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata); }
public interface ConditionContext { /** * Return the {@link BeanDefinitionRegistry} that will hold the bean definition * should the condition match. */ BeanDefinitionRegistry getRegistry(); /** * Return the {@link ConfigurableListableBeanFactory} that will hold the bean * definition should the condition match. */ ConfigurableListableBeanFactory getBeanFactory(); /** * Return the {@link Environment} for which the current application is running. */ Environment getEnvironment(); /** * Return the {@link ResourceLoader} currently being used. */ ResourceLoader getResourceLoader(); /** * Return the {@link ClassLoader} that should be used to load additional classes. */ ClassLoader getClassLoader(); }
下面是一个例子:
public interface RunEnvironment { public void where(); }
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.env.Environment; import org.springframework.core.io.ResourceLoader; import org.springframework.core.type.AnnotatedTypeMetadata; /** * bean是否加载的条件 * @author hasee * */ public class WindowsConditional implements Condition { public boolean matches(ConditionContext context, AnnotatedTypeMetadata am) { //可以检查bean定义 BeanDefinitionRegistry register = context.getRegistry(); //可以检查bean是否存在,甚至探查bean的属性 ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //检查环境变量是否存在以及它的值是什么 Environment environment = context.getEnvironment(); //返回类加载器,可以检查类是否存在 ClassLoader classLoader = context.getClassLoader(); //检查所加载的资源 ResourceLoader resourceLoader = context.getResourceLoader(); String osName = context.getEnvironment().getProperty("os.name"); System.out.println(osName); return osName.contains("Windows"); } }
import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; /** * bean是否加载的条件 * @author hasee * */ public class LinuxConditional implements Condition { public boolean matches(ConditionContext context, AnnotatedTypeMetadata arg1) { String osName = context.getEnvironment().getProperty("os.name"); System.out.println(osName); return osName.contains("Linux"); } }
public class WindowsEnvironment implements RunEnvironment { public void where() { System.out.println("Run in Windows"); } }
public class LinuxEnvironment implements RunEnvironment { public void where() { System.out.println("Run in Linux"); } }
@Configuration public class ConditionalConfig { //spring会遍历下面的条件,只生成符合的bean @Bean //只有满足WindowsConditional的条件此类才加载 @Conditional(WindowsConditional.class) public RunEnvironment getWindows() { return new WindowsEnvironment(); } @Bean @Conditional(LinuxConditional.class) public RunEnvironment getLinux() { return new LinuxEnvironment(); } }
import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.Chapter3.conditional.config.ConditionalConfig; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes= {ConditionalConfig.class}) public class ConditionalTest { @Autowired private RunEnvironment runEnvironment; @Test public void conditionalTest() { runEnvironment.where(); } } 结果输出为: Windows 8.1 Windows 8.1 Run in Windows
相关文章推荐
- SPRING IN ACTION 第4版笔记-第三章ADVANCING WIRING-009-用SPEL给bean运行时注入依赖值
- spring in action 学习笔记(七)注入内部bean
- 【Spring in Action】Spring的AOP基础知识及切面运用
- spring基础知识1:bean属性注入
- SPRING IN ACTION 第4版笔记-第三章ADVANCING WIRING-006-给bean运行时注入值(Environment,Property文件)
- (Spring In Action)bean注入类型的限定
- SPRING IN ACTION 第4版笔记-第三章ADVANCING WIRING-007-给BEAN运行时注入值placeholder、@Value
- spring in action 学习笔记(六)通过setter注入bean属性
- SPRING IN ACTION 第4版笔记-第二章-003-以Java形式注入Bean、@Bean的用法
- Spring实战(第4版) Spring Inaction 笔记(第二章)bean深入
- (Spring In Action)bean的name和id
- spring(基础六) spring中Bean属性为集合的注入方式
- Sping in Action读书笔记之一----------Bean的各种注入操作
- SPRING IN ACTION 第4版笔记-第二章WIRING BEANS-007-以set方法注入<property>\p-namespace\util-space
- Spring in Action(第二章 装配 Bean)学习笔记
- Spring In Action 01 ---装配Bean
- 《spring in action》--bean的作用域
- Spring in action 01 -- 装配 Bean(@Autowired)
- spring学习总结(四)---Spring基础知识(二:spring的注入方式)
- spring in action-装配Bean