spring:《spring实战》读后感二

1. 装配(wiring)

    创建应用对象之间协作关系的行为称为装配(wiring), 这也是依赖注入(DI)的本质.

2. spring装配机制:     

      1). 在XML中进行显式配置。


      2). 在Java中进行显式配置。

public interface CompactDisc {
	void play();
}



import org.springframework.stereotype.Component;

/*
 *   @Component注解。 这个简单的注解表明该类会作为组件类, 
 * 并告知Spring要为这个类创建bean。 
 */ 
public class SgtPeppers implements CompactDisc{

	@Override
	public void play() {
		System.out.println("config the beatles sing sgt. Pepper lonely hearts club band2");
	}
}



public class CDPlayer{

	private CompactDisc cd;
	
	public CDPlayer(CompactDisc cd){
		this.cd = cd;
	}
	
	public void play() {
		cd.play();
	}
}


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/*
 * @Configuration注解表明这个类是一个配置类, 
该类应该包含在Spring应用上下文中如何创建bean的细节。
 */
@Configuration
public class CDPlayerConfig {

	/*
	   @Bean注解会告诉Spring这个方法将会返回一个对象,该对象要注册
         为Spring应用上下文中的bean。方法体中包含了最终产生bean实例的逻辑。
	 */
	@Bean
	public CompactDisc sgtPeppers(){
		return new SgtPeppers();
	}
	
	@Bean
	public CDPlayer cdPlayer(CompactDisc cd){
		return new CDPlayer(cd);
	}
}


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;

@RunWith(SpringJUnit4ClassRunner.class)  // 自动创建Spring的应用上下文
/* 
  @ContextConfiguration会告诉它需要在CDPlayerConfig中加载配置。 
因为CDPlayerConfig类中包含了@ComponentScan 
*/
@ContextConfiguration(classes=CDPlayerConfig.class)
public class MyTest {

  @Autowired
  private CompactDisc cd;
  
  @Autowired
  private CDPlayer player;
  
  @Test
  public void test01(){
	  cd.play();	
	  player.play();
  }
}


      3). 隐式的bean发现机制和自动装配。

          spring从两个角度来实现自动化装配:  1). 组建扫描(component scanning): spring会自动发现应用上下文中所创建的bean。

                                                                      2). 自动装配(autowiring):spring自动满足bean之间的依赖。

public interface CompactDisc {
	void play();
}



import org.springframework.stereotype.Component;

/*
 *   @Component注解。 这个简单的注解表明该类会作为组件类, 
 * 并告知Spring要为这个类创建bean。 
 */ 
@Component
public class SgtPeppers implements CompactDisc{

	@Override
	public void play() {
		System.out.println("the beatles sing sgt. Pepper lonely hearts club band");
	}
}




import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/*
 * 组件扫描默认是不启用的
 * @ComponentScan注解启用了组件扫描 
 * @ComponentScan默认会扫描与配置类相同的包。Spring将会扫描这个包以及这个包下的所有子包, 查找带
有@Component注解的类。
 */
@Configuration
@ComponentScan
public class CDPlayerConfig {

}


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;

@RunWith(SpringJUnit4ClassRunner.class)  // 自动创建Spring的应用上下文
/* 
  @ContextConfiguration会告诉它需要在CDPlayerConfig中加载配置。 
因为CDPlayerConfig类中包含了@ComponentScan 
*/
@ContextConfiguration(classes=CDPlayerConfig.class)
public class MyTest {
	
  @Autowired
  CompactDisc cd;
  
  @Test
  public void test01(){
	  cd.play();	  
  }
}

 当然如果你喜欢使用xml启动组件扫描,那么如下xml配置可以代替@ComponentScan

 3. 在JavaConfig中引用xml配置

   

public interface CompactDisc {
	void play();
}

import java.util.List;

public class BlankDisc implements CompactDisc{

	private String title;
	private String artist;
	private List<String> tracks;
	public BlankDisc(String title, String artist, List<String> tracks) {
		super();
		this.title = title;
		this.artist = artist;
		this.tracks = tracks;
	}

	@Override
	public void play() {
		System.out.println("xml,javaconfig混合使用");
		System.out.println("Playing "+title+" by"+artist);
		for(String track : tracks){
			System.out.println("-Track: "+track);
		}
	}
}


public class CDPlayer{

	private CompactDisc cd;
	
	public CDPlayer(CompactDisc cd){
		this.cd = cd;
	}
	
	public void play() {
		cd.play();
	}
}



import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/*
 * @Configuration注解表明这个类是一个配置类, 
该类应该包含在Spring应用上下文中如何创建bean的细节。
 */
@Configuration
public class CDPlayerConfig {
	
     /*
	   @Bean注解会告诉Spring这个方法将会返回一个对象,该对象要注册
         为Spring应用上下文中的bean。方法体中包含了最终产生bean实例的逻辑。
	 */
	@Bean
	public CDPlayer cdPlayer(CompactDisc cd){
		return new CDPlayer(cd);
	}
}


import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;

@Configuration
@Import(CDPlayerConfig.class)
@ImportResource("classpath:applicationContext.xml")
public class SoundSystemConfig {
	
}



import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)  // 自动创建Spring的应用上下文
/* 
  @ContextConfiguration会告诉它需要在CDPlayerConfig中加载配置。 
因为CDPlayerConfig类中包含了@ComponentScan 
*/
@ContextConfiguration(classes=SoundSystemConfig.class)
public class MyTest {

  //@Autowired
  //private CompactDisc cd;
  
  @Autowired
  private CDPlayer player;
  
  @Test
  public void test01(){
	player.play();
  }
}

 xml配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- bean definitions here -->
  <bean id="blankDisc" class="com.ag.test5.BlankDisc">
  	<constructor-arg value="sgt. Pepper"/>
  	<constructor-arg><value>the beatles</value></constructor-arg>
  	<constructor-arg>
  		<list>
  			<value>getting better</value>
  			<value>fixing a hole</value>
  		</list>
  	</constructor-arg>
  </bean>
</beans>

4. 条件化的bean

    Spring 4引入了一个新的@Conditional注解, 它可以用到带有@Bean注解的方法上。 如果给定的条件计算结果为true, 就会创建这个bean, 否则的话, 这个bean会被忽略。

5. 处理自动装配的歧义性

     发生歧义性的时候, Spring提供了多种可选方案来解决这样的问题。 你可以将可选bean中的某一个设为首选(primary) 的
bean(使用@Primary注解), 或者使用限定符(qualifier) 来帮助Spring将可选的bean的范围缩小到只有一个bean。

     Cake,Cookies都实现了Dessert接口,但是注入到Dessert类型时, 会将Cookies注入进去,避免了"org.springframework.beans.factory.NoUniqueBeanDefinitionException"

   

6. bean的作用域

 7. 运行时值注入

  如果希望避免硬编码值, 而是想让这些值在运行时再确定。如下,我们不希望把字符串写死。

  为了实现这些功能, Spring提供了两种在运行时求值的方式:

      1)。 属性占位符(Property placeholder) 。 

      占位符的形式为使用"${}"包装的属性名称。

       为了使用占位符, 我们必须要配置一个PropertyPlaceholderConfigurer bean或PropertySourcesPlaceholderConfigurer bean。 从Spring3.1开始, 推荐使用PropertySourcesPlaceholderConfigurer, 因为它能够基于Spring Environment及其属性源来解析占位符。


      2)。Spring表达式语言(SpEL  Spring Expression Language)

     SpEL拥有很多特性, 包括:
             ①使用bean的ID来引用bean;
             ②调用方法和访问对象的属性;
             ③对值进行算术、 关系和逻辑运算;
             ④正则表达式匹配;
             ⑤集合操作。

    SpEL表达式要放到“#{ ... }”之中

       SpEL可以表示字面值: 浮点数(#{3.14159}), String(#{'hello'})值以及Boolean(#{true})值。

       SpEL还可以引用bean(#{sgtPeppers})、 属性(#{sgtPeppers.artist})和方法(#{artistSelector
.selectArtist()}
)

       SpEL还可以使用T()在表达式中使用类型。

                                                            用来操作表达式值的SpEL运算符

运算符类型 运 算 符
算术运算 +、 -、 * 、 /、 %、 ^
比较运算 < 、 > 、 == 、 <= 、 >= 、 lt 、 gt 、 eq 、 le 、 ge
逻辑运算 and 、 or 、 not 、 │
条件运算 ?: (ternary) 、 ?: (Elvis)
正则表达式 matches

      例如: #{2 * T(java.lang.Math).PI  *  circle.redius}    // 使用了乘法运算符(*)
     尽量让表达式简洁

      

发布了557 篇原创文章 · 获赞 40 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/m0_37564426/article/details/103861445
今日推荐