三、spring中高级装配(1)
2021-06-26 17:04
标签:code method initial database time 结果 ace doc develop 大概看了一下第三章的内容,我从项目中仔细寻找,始终没有发现哪里有这种配置,但是看完觉得spring还有这么牛B的功能啊,spring的厉害之处,这种设计程序的思想,很让我感慨。。。 一、环境与profile (1)配置profile bean 面对这样的需求:想出一种方法来配置DataSource,使其在每种环境下都会选择最为合适的配置,你会如何做呢?看看spring所提供的解决方案。spring中引入了bean profile的功能。在Java配置中,可以使用@Profile 注解指定某个bean属于哪一个profile。 1)在Java类中配置profile bean 2)在XML中配置profile bean 2)激活 profile profile bean 配置OK了,如何来激活配置的bean呢?依赖两个独立的属性:spring.profiles.active 和 spring.profiles.default。设置了spring.profiles.active属性的话,那么它的值就会来确定哪个profile是激活的,如果设置了spring.profiles.default属性,那么spring 会查找spring.profiles.default的值,如果两个属性都设置的话,肯定会优先spring.profiles.active属性对应的profile bean 装配 多种方式设置这两个属性: 1))作为DispatcherServlet的初始化参数 2))作为web应用的上下文参数 3))作为JNDI条目 4))作为环境变量 5))作为JVM的系统属性 6))在集成测试上,使用@ActiveProfiles注解设置 web.xml 中设置默认的profile 二、条件化的bean spring4引入了一个新的@Conditional注解,它可以用到带有@Bean注解的方法上。如果给定的条件计算结果为true,则会创建这个bean,否则的话,这个bean会被忽略。 注:这里讲解了两个比较特殊的接口,一个是ConditionContext,一个是AnnotatedTypeMetadata,做一个说明: 注:spring4 中对@Profile注解进行了重构,使其基于@Conditional 和 Condition实现,@Profile在spring4 中的实现: 三、spring中高级装配(1) 标签:code method initial database time 结果 ace doc develop 原文地址:https://www.cnblogs.com/ssh-html/p/9655295.htmlpackage com.myapp;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
//@Profile注解应用在累计别上。它会告诉spring这个配置类中的bean只有在dev profile 激活时才会创建,没有激活,则不会创建
@Configuration
@Profile("dev")
public class DevelopmentProfileConfig{
return new
EmbeddDatabaseBuilder().setType(EmbeddedDatebaseType.H2).
addScript("classpath:schema.sql").addScript("classpath:test-
data.sql").build();
}
package com.myapp;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jndi.JndiObjectFactoryBean;
//@Profile注解应用在累计别上。它会告诉spring这个配置类中的bean只有在prod profile 激活时才会创建,没有激活,则不会创建
@Configuration
@Profile("prod")
public class ProductiontProfileConfig{
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiName("jdbc/myDS");
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
return (DataSource) jndiObjectFactoryBean.getObject();
}
//可以将这两个bean的声明放置在同一个配置类中
package com.myapp;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.jndi.JndiObjectFactoryBean;
@Configuration
public class DateSourceConfig{
//为dev profile装配bean
public DataSource embeddedDataSource(){
return new
EmbeddDatabaseBuilder().setType(EmbeddedDatebaseType.H2).
addScript("classpath:schema.sql").addScript("classpath:test-
data.sql").build();
}
//为prod profile 装配bean
public DataSource jbdiDataSource(){
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiName("jdbc/myDS");
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
return (DataSource) jndiObjectFactoryBean.getObject();
}
}
//xml中配置的实际效果和在Java类中配置是一样的
//dev profile 的bean
//为上下文设置默认的profile
//条件化的创建bean
@Bean
@Conditional(MagicExistsCondition.class)
public MagicBean magicBean(){
return new MagicBean();
}
//@Conditional 将会通过Condition 接口进行条件对比
public interface Condition{
public boolean matches(ConditionContext ctcx,AnnotatedTypeMetadata metadata);
}
//在Contidion 中检查是否存在magic属性,满足这个条件,matches()方法返回true,则所有的@Conditional 注解上引用MagicExistsCondition的bean都会被创建
public class MagicExistsCondition implements Condition{
public boolean matches(ConditionContext context,AnnotatedTypeMetadata metadata){
Environment env = context.getEnvironment();
return env.containsProperty("magic");
}
}
public interface ConditionContext{
//检查bean的定义
BeanDefinitonRegistry getRegistry();
//检查bean是否存在,甚至探查bean的属性
ConfigurableListableBeanFactory getBeanFactory();
//检查环境变量是否存在以及它的值是什么
Environment getEnvironment();
//返回ResourceLoader所加载的资源
ResourceLoader getResourceLoader();
//返回ClassLoader加载并检查类是否存在
ClassLoader getClassLoader();
}
//检查带有@Bean注解的方法上还有什么其他的注解
public interface AnnotatedTypeMetadata{
boolean isAnnotated(String annotationType);
Map
/*
@Profile本身也使用了@Conditional注解,并且引用了ProfileCondition作为Condition实现,ProfileCondition在做出决策的过程中,考虑到了ConditionContext和AnnotatedTypeMetadata中多个因素
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@Document
@Conditional(ProfileCondition.class)
public @interface Profile{
String[] value();
}
上一篇:Python入门——练习
下一篇:java