博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第3章 高级装配
阅读量:6897 次
发布时间:2019-06-27

本文共 7335 字,大约阅读时间需要 24 分钟。

1、"profile bean"(Spring为那些和运行环境有关系的bean提供的配置。配置后,Spring会根据运行环境选取相应的bean)     (需要将这些bean放到profile bean中,并确保profile处于active状态) 2、使用java配置profile bean(使用@Profile注解指定bean属于哪个profile文件中)     例如:
//在类级别上使用profile bean    @Configuration    @profile("dev")    public class 配置类{        @Bean        public 需要的Bean 方法名(){            new 需要的Bean();        }    }
(同理:可以再创建一个类指定不同环境需要装配的bean)     //上面这个bean只有在dev profile文件被激活时才创建。如果dev 不是激活状态则忽略创建。(根据profile是否激活,装配不同的bean) 3、在方法级别上使用profile bean (Spring 3.2 开始可以再方法级别上使用Profile bean)
@Configuration    public class 配置类名{        @Bean        @Profile("dev")      //dev profile 装配的bean        public 开发环境需要的Bean 方法名(){            return new 开发环境需要的Bean();        }        @Bean        @Profile("prod")        //prod profile 装配的bean        public 运行环境需要的Bean 方法名(){            return new 运行环境需要的Bean();        }    }
4、在XML中配置Profile     1:每一个xml配置文件的
元素添加 profile = "" 例如:
...
2:使用嵌套
例如:
...
...
5、激活profile     配置profile的两个属性:         1:active(Spring.profiles.active):指定那个profile处于激活状态         2:default(Spring.profiles.default):如果没有配置active,会找default配置的值。            //如果都active和default都没有配置:不装配profile中的bean。     设置active和default属性:         1:作为DispatcherServlet的参数初始化             在web的Servlet配置中加:
spring.profiles.default
dev
2:作为Web应用的上下文         3:作为JNDI条目         4:作为环境变量         5:作为JVM的系统属性         6:在集成测试类上,使用@activeProfiles注解设置 6、条件化的bean     需求:希望一个bean在含有某个外部的jar是才创建,希望某个特定的bean声明后才创建,(总之就是有条件的创建bean)     在Spring 4之前很难做到。但是Spring 4 引入了 @Conditional 注解,他可以用在带有@Bean的注解方法上。     @Conditional:         如果给定的计算结果为true则创建bean,否则bean被忽略。     例如:         //假设有一个名为 MagicBean 的类,我们希望只有设置了环境属性 magic 时才实例化这个bean。         1:条件话创建bean:
@bean            @Conditional(MagicExistsCondition.class)    //设置条件。            public MagicBean magicBean(){                return new MagicBean();            }            //传给@Conditional的参数需要是Condition接口的实现。实现Condition接口只需要实现matches()方法,                //matches()方法返回值就是判断条件的结果。
2:判断条件:
public class MagicExistsCondition implements Condition{                public boolean matches(ConditionContext context , AnnotatedTypeMetadata metadata){                    Environment env = context.getEnvironment();                    return env.containsProperty("magic");                }            }            //本例中判断环境中是否有magic。
注意:             上面的例子只是使用了ConditionContext获取到了环境属性。实际开发中获取会根据更为负责的内容判断(但来源基本都是matches的参数):             ConditionContext:                 1:使用getRegistry()方法返回的BeanDefinitionRegistry检查bean的定义。                 2:使用getBeanFactory()方法返回的ConfigurableListtableBeanFactory()检查bean是否存在,探测bean的属性。                 3:使用getEnvironment()方法返回的ResourceLoader加载资源。                 4:使用getClassLoader()返回的ClassLoader加载并检测类是否存在。             AnnotatedTypeMetadata:                 这个接口可以检查带有@Bean的方法上还含有什么注解。                 1:使用isAnnotated()方法可以判断带有@Bean的方法是不是还有别的注解。                 2:借助别的方法可以检查方法上的其他注解及其属性。 7、处理自动装配的歧义性     自动装配时:只有一个Bean匹配到所需结果时才能装配成功,匹配到多个Bean阻碍了自动装配。     例如:
//需要自动装配的bean        @Autowired        public void setDessert(Dessert dessert){            this.dessert = dessert;        }
//Dessert 是一个接口。并且有三个类实现了该接口并且都是用@Component指定了该类作为bean:        @Component        public class Cake implements Dessert{...}        @Component        public class Cookies implements Dessert{...}        @Component        public class IceCream implements Dessert{...}
//当Spring试图给setDessert进行自动注入时:无法匹配到唯一的bean,抛出异常(NoUniqueBeanDefinitionException)。         虽然出现这种歧义性的概率非常小,当发生这种情况时我们可以通过             1:给其中一个bean设置首选。2:使用限定符将可选的bean缩小的一个。 8、标注首选的bean     在声明bean的时候可以使用@Primary设置一个设置首选的bean,当出现自动装配的歧义性时会选择这个bean。     1:@Component 和 @Primary组合声明首选:
@Component        @primary        public class IceCream implements Dessert{...}
2:Bean配置 和 Primary组合声明首选:         2.1:使用javaConfig配置:
@Bean            @Primary            public Dessert iceCream(){                return new IceCream();            }
2.2:使用xml配置bean(使用XML配置bean同样可以实现:)
注意:问题来了:如果同时配置了两个Primary,依然产生歧义。(无法最终锁定到一个bean上) 9、通过限定符将bean范围缩小。     ???????????????? 10、bean作用域:     Spring 应用上下文中所有的bean都是以单例的形式创建的,但是每次都调用一个实例是很不现实的(对象状态改变)。     Spring提供了多种作用域:可以基于这些作用域创建bean:         1:单例:在整个项目中只有一个bean实例(默认)         2:原型:每次注入或者通过Spring上下文获取的时候都会创建新的实例         3:会话:在Web应用中为每一个会话创建一个实例         4:请求:在Web应用中为每一个请求创建一个实例 11、选择bean的作用域:     1:@Component 和 @ Scope 结合         例如:
@Component            @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)     //声明作用域为 原型            public class xxx(...)
2:@Bean 和 @Scope 结合(在javaConfig中配置)        例如:
@Bean            @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)            public 需要的Bean 方法名(){                return new 需要的Bean();            }
使用Xml配置bean的情况:
12、使用会话和请求作用域     ????????????????? 13、在xml中声明作用域代理     ????????????????? 14、运行时值注入:     之前描述bean时使用了:         @Bean         public 需要的Bean 方法名(){return new 需要的Bean();}         
无论是使用什么方法注入,其实都是将关联的内容写死了。这种硬编码有时候是行不通的。 Spring提供了两种运行时求值的方法。: 1:属性占位符 2:Spring表达式语言 15、注入外部的值: 在Spring中处理外部值的最简单的办法是声明属性源,并且使用Spring的Environment检索。 例如:
@Configuration        @PropertySource("classPath:/com/xxx/yyy/app.properties")        //声明属性源        public class 配置类名{            @Autowired            Environment env;            @Bean            public 需要的Bean 方法名(){                return new 需要的Bean(env.getProperty("需要的属性"));    //检索指定的属性            }        }
16、Spring的Environment     Environment中的getProperty()方法有四个重载的方法:         1:String getProperty(String key)         2:String gegtProperty(String key , String defaultValue)         //添加了默认值         3:T getProperty(String key , Class
type) //将获取到的值转化为T类型(例如String -> Integer) 4:T getProperty(String key , Class
type , T defaultValue) 如果没有找到key也没有指定默认值,这种情况需要报告给程序,抛出异常: 5:getRequiredProperty() 例如:
@Configuration             @PropertySource("classPath:/com/xxx/yyy/app.properties")        //声明属性源             public class 配置类名{                 @Autowired                 Environment env;                 @Bean                 public 需要的Bean 方法名(){                     return new 需要的Bean(env.getRequiredProperty("key"));    //如果找不到,抛出异常(IllegalStateException)                 }             }
如果想要将属性解析为类:         6:getPropertyAsClass()         例如:
Class
<需要的类>
clazz = evn.getPropertyAsClass("key" , 需要的类.class);
Environment还提供了检索哪些profile处于active状态(具体看书)。 17、解析属性占位符:     1:在xml中配置:
//${key}将从某一个源获取。
2:如果使用组件扫描和自动装配(不配置xml了):
public BlankDisc (@Value("${key}") String title){            this.title = title;        }
注意:         为了使用占位符,需要配置一个             PropertyPlaceholderConfigurer bean                 或者             PropertySourcesPlaceholderConfigurer bean   (推荐)             (具体看书) 18、使用Spring表达式语言     ????????????????

转载于:https://www.cnblogs.com/Xmingzi/p/8856728.html

你可能感兴趣的文章
wps相关问题
查看>>
nginx 和php设置上传大小及可以提交的内容限制
查看>>
eclipse中打字中文突然变成繁体
查看>>
maven打包报错:Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.5:test
查看>>
【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】...
查看>>
深入理解计算机系统(1.3)------操作系统的抽象概念
查看>>
Win10 IoT C#开发 5 - 操作 IoT 设备内嵌 SQLite 数据库 CURD
查看>>
面向过程 VS 面向对象
查看>>
背水一战 Windows 10 (56) - 控件(集合类): ListViewBase - 基础知识, 拖动项
查看>>
剑指offer四之重建二叉树
查看>>
Eclipse工具栏太多,自定义工具栏,去掉调试
查看>>
iOS开发】之CocoaAsyncSocket使用
查看>>
使用ss命令代替 netstat
查看>>
Maven的作用及简介
查看>>
08-hibernate注解-多对多单向外键关联
查看>>
Tomcat下使用Druid配置JNDI数据源
查看>>
神经网络中embedding层作用——本质就是word2vec,数据降维,同时可以很方便计算同义词(各个word之间的距离),底层实现是2-gram(词频)+神经网络...
查看>>
SQL Server 临时表的删除
查看>>
ElasticSearch安装部署,基本配置(Ubuntu14.04)
查看>>
nginx优化缓冲缓存
查看>>