Spring依赖注入分析
发布时间:2021-12-07 13:31:19 所属栏目:教程 来源:互联网
导读:一、概述 Spring框架是以 简化Java EE应用程序的开发 为目标而创建的。Spring可以实现很多功能,但是这些功能的底层都依赖于它的两个核心特性,也就是依赖注入和面向切面编程。几乎Spring所做的任何事情都可以追溯到下述的一条或多条策略: 基于POJO的轻量级
一、概述 Spring框架是以 简化Java EE应用程序的开发 为目标而创建的。Spring可以实现很多功能,但是这些功能的底层都依赖于它的两个核心特性,也就是依赖注入和面向切面编程。几乎Spring所做的任何事情都可以追溯到下述的一条或多条策略: 基于POJO的轻量级和最小侵入性编程; 通过依赖注入和面向接口实现松耦合; 基于切面和惯例进行声明式编程; 通过切面和模板减少样板式代码。 Spring的三个基本愿景: 使用DI来实现低耦合 使用AOP切面实现高内聚 使用模板消除样板式代码,比如jdbcTemplate 二、Bean 容器是Spring框架的核心。Spring容器使用DI管理构成应用的组件(Bean),它会创建相互协作的组件之间的关联。毫无疑问,这些对象更简单干净,更易于理解和重用,更易于单元测试。 Spring为每个Bean定义了多种作用域,默认都是以单例的模式创建的: 单例(Singleton):在整个应用中,只创建bean的一个实例。 原型(Prototype):每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例。 会话(Session):在Web应用中,为每个会话创建一个bean实例。 请求(Rquest):在Web应用中,为每个请求创建一个bean实例。 Bean的生命周期: Spring自带了多种类型的上下文(适用于在普通类中利用Spring的上下文加载需要的Bean): AnnotationConfigApplicationContext:从一个或者多个的Java配置类中加载Spring的应用上下文 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(JavaConfig.class); AnnotationConfigWebApplicationContext:从一个或多个基于Java的配置类中加载Spring Web应用上下文。 ClassPathXmlApplicationContext:从类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类资源。 ApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext.xml"); FileSystemXmlapplicationcontext:从文件系统下的一个或多个XML配置文件中加载上下文定义。 XmlWebApplicationContext:从Web应用下的一个或多个XML配置文件中加载上下文定义。 三、依赖注入 1、@Component 表明该类会作为组件类,并告知Spring 要为这个类创建bean(这个bean的ID默认取名类名的首字母小写)。不过组件扫描默认是不启用的。我们还需要显示配置一下Spring,从而命令他去寻找带有@Component(类似的还有@Repository @service @controller)注解的类,并为他创建bean。有三种方式来配置Spring创建Bena: * 自动化装配的方式:1、建一个配置类。@Configuration 表明这个类是一个配置类 加上@ComponentScan(basePackages={"包名1","包名2"} 或者 basePackageClasses={包1的某个Class,包2的某个Class}) 会扫描和配置类相同的包,以及这个包下的所有子包。 2、Spring XML配置方式: <context:component-scan base-package=""/> * 在JavaConfig中进行显示配置(适用于第三方的类库组件装配到自己应用中) @Configuration public class JavaConfig { @Bean(name = "base64Util") public Base64Util getBase64Util(){ return new Base64Util(); } @Bean(name = "base64UtilExpand") //这种显示配置默认的Bean名是方法名。所以最好显示配置一下 public Base64UtilExpand getBase64UtilExpand(){ //对于这种创建的bean需要引用其他的bean。Spring是这样处理的:当引用到还没创建的bean的时候,Spring会拦截下这个引用,等到引用的bean的创建完成。已保证Spring bean的单例模式. return new Base64UtilExpand(getBase64Util()); } @Bean(name = "base64UtilExpand") public Base64UtilExpand getBase64UtilExpand(Base64Util base64Util){ return new Base64UtilExpand(base64Util); } } * 在XML中进行显示配置,最古老的方式,一般很少用,有两种方式注入,构造器注入和set注入: <!--构造器注入--> <bean id="cDPlayer" class="com.CDPlayer"> <constructor-arg ref="compactDisc"> </bean> <bean id="cDPlayer" class="com.CDPlayer"> <constructor-arg value="compactDisc"> </bean> <bean id="cDPlayer" class="com.CDPlayer"> <constructor-arg> <list> <value></value> </list> </constructor-arg> </bean> <!--setter注入--> <bean id="cDPlayer" class="com.CDPlayer"> <property name="compactDisc" ref="compactDisc"> </bean> <bean id="cDPlayer" class="com.CDPlayer"> <property name="compactDisc" value="compactDisc"><!--装配字面量:--> </bean> 装配集合 <bean id="cDPlayer" class="com.CDPlayer"> <property name="compactDisc" value="compactDisc"> <property name=""> <list> <value></value><!--装配集合--> </list> </property> </bean> 2、@scope 指定bean创建时的作用域,Spring默认创建单例模式的bean。但也有特殊的情况,这里需要说明的是如果某个类注入了Session 和 Request 作用域的Bean,因为这个Bean是在用户请求的时候产生的,在Spring 运行起来的时候并不存在。这里Spring是这样处理的:注入给对应Bean的一个代理,而当用户请求产生session 或者 request 作用域Bean的时候,由这个代理连接到相应的Bean处理请求... 原型:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 会话:(接口)@Scope(value = WebApplicationContext.SCOPE_SESSION,proxyMode = ScopedProxyMode.INTERFACES) (具体类)@Scope(value = WebApplicationContext.SCOPE_SESSION,proxyMode = ScopedProxyMode.TARGET_CLASS) 当然也可以在XML中配置: <bean id="shoppingCart2" class="com.entity.ShoppingCart2" scope="session"> <aop:scoped-proxy proxy-target-class="false"/> </bean> 3、限定符(用的较少) @Profile 决定哪些bean可以被激活。需要注意的是没有指定profile的bean始终都会被创建,与激活哪个profile没有关系。 @Conditional中给定了一个Class,这个Class 实现了Codition 接口的matches 方法,该方法返回true 则生成bean,否则不生成。 @primary 常见的情况是一个接口仅有一个实现类,所以使用@Autowire的后,Spring可以走到对应的实现类。如果一个接口有多个实现类呢?@Component 和 @primary 同时使用,标注哪个实现类优先被使用。 @Qualifier 使用@primary 仍然无法保证哪个bean被选择,因为可以在多个实现类上使用@primary。所以可以在实现类用@Qualifter("bean")名指定bean的名字。并在@Autowire 注入接口的时候是使用Qualifier 指定实现类的bean名。当然,也可以用@Resource(name=" ")指定类的名称。 4、读取 properties 文件 (1) @PropertySource 会引用一个类路径上的properties的文件,并利用Environment类获取properties的变量值。例如:@PropertySource("classpath:mongo.properties") @Configuration @PropertySource("classpath:mongo.properties") public class JavaConfig { @Bean(name = "mongoUtil") public MongoUtil getMongoUtil(Environment env){ return new MongoUtil(env.getProperty("mongo.host"), env.getProperty("mongo.port"), env.getProperty("mongo.database"), env.getProperty("mongo.username"), env.getProperty("mongo.password")); } } (2) 占位符 Spring 中占位符的形式是使用${}的方式。在代码文件中我们可以使用@Value注解将配置文件的值注入到变量中。为了使用占位符,我们必须配置一个PropertySourcesPlaceholderConfigurer 的类,已生成相关的bean,或者通过XML配置让Spring为我们自动生成: @Configuration @PropertySource("classpath:mongo.properties") public class JavaConfig { @Bean(name = "propertySourcesPlaceholderConfigurer") public PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer(){ return new PropertySourcesPlaceholderConfigurer(); } } 或者: <!--提供读取配置文件可以使用Spring占位符${}--> <context:property-placeholder location="classpath:mongo.properties" file-encoding="utf-8" /> 用法如下: @RunWith(SpringJUnit4ClassRunner.class) //@ContextConfiguration(classes = JavaConfig.class) @ContextConfiguration(locations = "classpath:applicationContext.xml") public class Test06 { @Value("${mongo.host}") private String host; @Test public void test06(){ System.out.println(host); } } 四、Expression Language Spring Expression Language,简称SpEL,是一种非常灵活的表达式语言,拥有很多特性,包括: 使用bean的ID来引用bean; 调用方法和访问对象的属性; 对值进行算术、关系和逻辑运算; 正则表达式匹配; 集合操作。 SpEL 采用#{}的形式: 1、代表字面值:#{3.14} #{'Hello'} #{false} 2、引用bean、属性、方法 #{bean} #{bean.artist} #{bean.toUpperCase()} #{bean?.toUpperCase()}(表示如果bean为null 就返回null,不调用方法) 3、引用某个类 #{T{java.lang.Math}.PI} 4、三元表达式 #{bean.score > 1000 ? "win":"los"} 判空 #{bean.score ?: "win"} 5、正则表达式 #{bean.email matches '表达式'} 6、计算集合 #{bean.song[4].title} 查询运算符(.?) #{bean.songs.?[artist eq 'hello']} 匹配第一个 (.^) #{bean.songs.^[artist eq 'hello']} 匹配最后一个 (.$) : #{bean.songs.$[artist eq 'hello']} 投影运算符 (.!) #{bean.songs.![title]} <bean id="carl" class="com.springinaction.springidol.Instrumentalist"> <property name="song" value="#{kenny.song}" /> </bean> public static class FieldValueTestBean { @Value("#{ systemProperties['user.region'] }") private String defaultLocale; public void setDefaultLocale(String defaultLocale) { this.defaultLocale = defaultLocale; } public String getDefaultLocale() { return this.defaultLocale; } } Spring为SpEL创造了两种特殊的选择属性方式:systemEnvironment和systemProperties. systemEnvironment包含了应用程序所在机器上的所有环境变量。 systemProperties包含了java应用程序启动时所设置的所有属性。 五、JUnit 测试 @RunWith(SpringJUnit4ClassRunner.class) //@ContextConfiguration(classes = JavaConfig.class) 加载配置类 @ContextConfiguration(locations = "classpath:applicationContext.xml") //加载配置文件 public class Test02 { @Resource(name = "iceCream") private Dessert dessert; @Test public void test02(){ dessert.sys(); } } ![]() (编辑:牡丹江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐