Spring的核心是dependency injection (DI) and aspect-oriented programming (AOP).
java
第一章概览一下什么是Spring,以及DI和AOP是怎么解耦(decoupling )应用组件的。web
第二章讲模块、bean怎么链接起来,咱们会了解spring提供的三种配置方式:自动配置,基于java的配置和用xml配置。【wiring beans,不清楚标准翻译法,暂翻译为链接,装配,反正大概就是这个意思】算法
第三章延续第二章讲一些高级的技术技巧,包括带有特定条件的配置,自动装配时的歧义处理,域,以及Spring表达式语言。【Spring Expression Language)】spring
第四章讲Spring的AOP如何解耦全路服务(好比安全控制及审计)【decouple system-wide services (such as security and auditing) 】数据库
3.1 环境与配置文件:数据库配置,加密算法,外部系统的集成等都是一些开发环境,一个可行的方案是利用好比说maven的profile,经过选用不一样的类或xml文件进行rebuild来实现不一样环境下的应用搭建,spring有比这个更好的方案。安全
3.1.1 java上配置@Profile来达到目的,3.2以上的spring能够把这个注解放到method上。相应的,xml在顶级或者子集的beans上增长profile属性来达到这个目的。session
3.1.2 profile激活方式,两个级别:spring.profiles.active ,spring.profiles.default. 前者优先级高,后者优先级低,六种方式:初始化DispatcherServlet 的参数,web应用的上下文参数,JNDI键值对,环境变量,JVM系统属性,继承测试类的@ActiveProfiles
注解。自由配对组合。maven
3.2 条件beanide
@Conditional注解,参数为一个实现了Condition接口的类.Condition的matches方法传入的参数有ConditionContext:测试
1 public interface ConditionContext { 2 BeanDefinitionRegistry getRegistry(); 3 ConfigurableListableBeanFactory getBeanFactory(); 4 Environment getEnvironment(); 5 ResourceLoader getResourceLoader(); 6 ClassLoader getClassLoader(); 7 }
以及AnnotatedTypeMetadata :
public interface AnnotatedTypeMetadata { boolean isAnnotated(String var1); Map<String, Object> getAnnotationAttributes(String var1); Map<String, Object> getAnnotationAttributes(String var1, boolean var2); MultiValueMap<String, Object> getAllAnnotationAttributes(String var1); MultiValueMap<String, Object> getAllAnnotationAttributes(String var1, boolean var2); }
事实上,Profile就是经过这种方式实现的。
1 @Target({ElementType.TYPE, ElementType.METHOD}) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Conditional({ProfileCondition.class}) 5 public @interface Profile { 6 String[] value(); 7 }
1 class ProfileCondition implements Condition { 2 ProfileCondition() { 3 } 4 5 public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 6 if(context.getEnvironment() != null) { 7 MultiValueMap attrs = metadata.getAllAnnotationAttributes(Profile.class.getName()); 8 if(attrs != null) { 9 Iterator var4 = ((List)attrs.get("value")).iterator(); 10 11 Object value; 12 do { 13 if(!var4.hasNext()) { 14 return false; 15 } 16 17 value = var4.next(); 18 } while(!context.getEnvironment().acceptsProfiles((String[])((String[])value))); 19 20 return true; 21 } 22 } 23 24 return true; 25 } 26 }
3.3 若是你足够敏锐的话,在以前的章节就应该有一个问题萦绕在你的脑海中,那就是若是同一个接口有多个实现类被放到bean声明中,或者多个@Component注解被ComponentScan发现,这中状况该如何处理?
3.3.1用@Primary能够指定一个默认选择。xml中则是primary=“true”
3.3.2 在@AutoWired或@Inject上用@Qualifier注解指定一个全限定名,bean的全限定名默认是id,id默认是首字母小写的类名。固然,全限定名和id都是能够指定的。另外一种方式是建立自定义的限定注解,所有注解一致时匹配。
3.4 bean的域
按前面说的,正常状况下bean只会复用同一个引用,也就是说,至关于每一个bean都是单例模式。除了这种模式外还有其余模式可供选择,Prototype 每次都建立一个新的bean,用了就扔,Session 在web应用中没建立一个session就会new一个,Request 在web应用中对于一个Request,new一个bean。
java注解:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) ;xml属性:scope=“prototype”
3.4.1 request和session域.TODO:web看完后我再回头修改。