Spring梳理(一)

        技术如果一段时间不练,再次捡起来就相当于一次重复学习,为加深理解和降低二次学习成本,spring系列大部分将转载 张开涛的博客(人家写的好而且全面),中间会加入一些自己的理解和总结。
        说起spring,就会想起控制反转和依赖注入,这也是Spring的灵魂所在,再有其他的,可能就是一堆的配置文件或难搞懂的注解了,概念性的东西,下面两句话就够了。
        IoC 控制反转(IoC容器控制对象) IOC不是一种技术,而是一种思想,ioc容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

        DI(Dependency):依赖注入,通过配置,无需代码而指定目标需要的资源,完成自身的业务逻辑,而无需关心具体资源来自何处,由谁实现。

      HelloWorld,来体会spring的便捷之处

Spring下载地址: http://repo.spring.io/release/org/springframework/spring/
新建Dynamic web Project,拷入如下jar包:

        
       src下新建目录com.hello,这里不考虑分包,接下来几个文件都放在该目录下。

public interface HelloApi {
	public void say();
}
public class HelloImpl implements HelloApi {
	@Override
	public void say() {
		System.out.println("hello world!");
	}
}
项目右键->build path->java Build path->libraries->add library,加入JUnit 4包:
public class HelloTest {
	@Test
	public void testHelloWorld(){
	        //1、读取配置文件实例化一个IoC容器 
		ApplicationContext ctx=new ClassPathXmlApplicationContext("/com/hello/bean.xml");
		//2、从容器中获取Bean,注意此处完全“面向接口编程,而不是面向实现”  
		HelloApi api=ctx.getBean("hello",HelloApi.class);
		//3、执行业务逻辑  
		api.say();
	}
}
新建bean.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"  
xmlns:context="http://www.springframework.org/schema/context"  
xsi:schemaLocation="  
http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
http://www.springframework.org/schema/context    http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 
  <!-- id 表示你这个组件的名字,class表示组件类 -->  
<bean id="hello" class="com.hello.HelloImpl"></bean>  
</beans> 
部署完成后,到这里一个简单的helloworld就完成了。
 =============================分界线========================================
       IoC容器的代表就是org.springframework.beans包中的 BeanFactory接口,BeanFactory接口提供了IoC容器最基本功能;而org.springframework.context包下的ApplicationContext接口扩展了BeanFactory,还提供了与Spring AOP集成、国际化处理、事件传播及提供不同层次的context实现 (如针对web应用的WebApplicationContext)。

容器实现一览(读取配置文件的几种方法)
  -  XmlBeanFactory:BeanFactory实现,通过了基本的IoC容器功能,课程classpath或文件系统等获取资源
     1 File file=new File("fileSystemConfig.xml");
Resource resource=new FileSystemResource(file);
BeanFactory beanFactory=new XmlBeanFactory(resource);

     2  Resource resource=new ClassPathResource("classpath.xml");
BeanFactory beanFactory=new XmlBeanFactory(resource);

 -   ClassPathXmlApplicationContext: ApplicationContext实现,从classpath获取配置文件
BeanFactory beanFactory=new ClassPathXmlApplicationContext("classpath.xml");

 -   FileSystemXmlApplicationContext: AplicationContext实现,从文件系统中获取配置文件
      BeanFactory beanFactory=new FileSystemXmlApplicationContext("fileSsytemConfig.xml");

      简单说, BeanFactory提供了IoC容器最基本功能,而 ApplicationContext 则增加了更多支持企业级功能支持。ApplicationContext完全继承BeanFactory,因而BeanFactory所具有的语义也适用于ApplicationContext。
      总结以上:读取配置文件其实就两种!分别是classpath(类路径)和文件系统中获取,而最常用的是从classpath下获取(上边标红),其他了解即可!

xml配置的结构

  一般配置文件结构如下:
	<beans>  
	    <!--导入其他配置文件的bean定义,可以放在beans下的任意位置,没有顺序关系,当然也可以把这些配置文件构造为一个数组
	       (new String[] {“config1.xml”, config2.xml})传给ApplicationContext实现进行加载多个配置文件
	    -->
	    <import resource=”resource1.xml”/>  
	    <bean id=”bean1”class=””></bean>  
	    <bean id=”bean2”class=””></bean>  
	<bean name=”bean2”class=””></bean>  
		<!--alias定义bean别名-->
	    <alias alias="bean3" name="bean2"/>  
	    <import resource=”resource2.xml”/>  
	</beans>  

bean命名  ------你知道“茴香豆”的“茴”字有几种写法吗?

      每个Bean可以有一个或多个id(或称之为标识符或名字),在这里我们把第一个id称“标识符”,其余id叫做“别名”;这些id在IoC容器中必须唯一。
      下面来看bean的id指定方式
        1 不指定id,只配置必须的全限定类名,由IoC容器为其生成一个标识,客户端必须通过接口“T getBean(Class<T> requiredType)”来获取Bean
BeanFactory beanFactory=new ClassPathXmlApplicationContext("namingBean1.xml");
HelloApi hellApi=beanFactory.getBean(HelloApi.class);
hello.sayHello();
        2 指定id,必须在IoC容器中 唯一
<bean id=” bean” class=“com.helloworld.HelloImpl”/>
		BeanFactory beanFactory=new ClassPathXmlApplicationContext("namingBean1.xml");
		HelloApi hellApi=beanFactory.getBean("Bean",HelloApi.class);
		hello.sayHello();	
       3 指定name,这样name就是“标识符”,必须在Ioc容器中 唯一
<bean name=“bean” class=” com.hello.HelloImpl”/> 
		BeanFactory beanFactory=new ClassPathXmlApplicationContext("namingBean1.xml");
		HelloApi hellApi=beanFactory.getBean("Bean",HelloApi.class);
		hello.sayHello();
       4 指定id和name,id就是标识符,而name就是别名,必须在Ioc容器中 唯一
<bean id=”bean1”name=”alias1” class=“com.hello.HelloImpl”/>  
<!-- 如果id和name一样,IoC容器能检测到,并消除冲突 -->  
<bean id="bean3" name="bean3" class="com.hello.HelloImpl"/>
		BeanFactory beanFactory = new ClassPathXmlApplicationContext("namingbean4.xml");  
		//根据id获取bean  
		HelloApi bean1 = beanFactory.getBean("bean1", HelloApi.class);  
		bean1.sayHello();  
		//根据别名获取bean  
		HelloApi bean2 = beanFactory.getBean("alias1", HelloApi.class);  
		bean2.sayHello();  
		//根据id获取bean  
		HelloApi bean3 = beanFactory.getBean("bean3", HelloApi.class);  
		bean3.sayHello();  
		String[] bean3Alias = beanFactory.getAliases("bean3");  
		//因此别名不能和id一样,如果一样则由IoC容器负责消除冲突  
		Assert.assertEquals(0, bean3Alias.length);  
        5 指定多个name,多个name用","、";"、""分割,第一个被用作标识符,其他的(alias1、alias2、alias3)是别名,所有标识符也必须在Ioc容器中唯一
<bean name=” bean1;alias11,alias12;alias13 alias14”  class="com.hello.HelloImpl"/>     
<!-- 当指定id时,name指定的标识符全部为别名 -->  
<bean id="bean2" name="alias21;alias22"  class="com.hello.HelloImpl"/>
		BeanFactory beanFactory =  new ClassPathXmlApplicationContext("namingbean5.xml");  
		//1根据id获取bean  
		HelloApi bean1 = beanFactory.getBean("bean1", HelloApi.class);  
		bean1.sayHello();  
		//2根据别名获取bean  
		HelloApi alias11 = beanFactory.getBean("alias11", HelloApi.class);  
		alias11.sayHello();  
		//3验证确实是四个别名         
		String[] bean1Alias = beanFactory.getAliases("bean1");  
		System.out.println("=======namingbean5.xml bean1 别名========");  
		for(String alias : bean1Alias) {  
		System.out.println(alias);  
		}  
		Assert.assertEquals(4, bean1Alias.length);  
		//根据id获取bean  
		HelloApi bean2 = beanFactory.getBean("bean2", HelloApi.class);  
		bean2.sayHello();  
		//2根据别名获取bean  
		HelloApi alias21 = beanFactory.getBean("alias21", HelloApi.class);  
		alias21.sayHello();  
		//验证确实是两个别名  
		String[] bean2Alias = beanFactory.getAliases("bean2");  
		System.out.println("=======namingbean5.xml bean2 别名========");  
		for(String alias : bean2Alias) {  
		System.out.println(alias);  
		}     
		Assert.assertEquals(2, bean2Alias.length); 
    从定义来看,name或id如果指定它们中的一个时都作为“标识符”,那为什么还要有id和name同时存在呢?这是因为当使用基于XML的 配置元数据时,在XML中id是一个真正的XML id属性,因此当其他的定义来引用这个id时就体现出id的好处了,可以利用XML解析器来验证引用的这个id是否存在,从而更早的发现是否引用了一个不存在的bean,而使用name,则可能要在真正使用bean时才能发现引用 一个不存在的bean。
     Bean命名约定:Bean的命名遵循XML命名规范,但最好符合Java命名规范,由“字母、数字、下划线组成“,而且应该养成一个良好的命名习惯, 比如采用“驼峰式”,即第一个单词首字母开始,从第二个单词开始首字母大写开始,这样可以增加可读性。
    总结:“茴香豆”的“茴”字写法虽多,但都是一个意思。id和name都能找到bean,都不能有重复,且都遵循一定命名规则(不能以数字符号打头,尽量使用字母下划线数字组合,写其他的纯自找不自在)。

实例化Bean

     Spring IoC容器则需要根据Bean定义里的配置元数据使用反射机制来创建Bean。有3种方式:构造器静态工厂实例化工厂方法。
     还是以上面helloword的例子来演示:
     1.构造方法,在HelloApi中加入两个构造器,一个是默认的,一个是带参的

	public class HelloImpl implements HelloApi {
		private String msg;
		public HelloImpl(){
			this.msg="Hello World! construct";
		}
		public HelloImpl(String msg){
			this.msg=msg;
		}
		@Override
		public void say() {
			System.out.println(msg);
		}
        }
	<bean name="bean1" class="com.HelloImpl"/>  
	<!-- 指定构造器参数 -->  
	     <constructor-arg index="0" value="Hello Spring!"/>  
	</bean>    

     2、使用静态工厂方式实例化Bean,使用这种方式除了指定必须的class属性,还要指定factory-method属性来指定实例化Bean的方法,而且使用静态工厂方法也允许指定方法参数,spring IoC容器将调用此属性指定的方法来获取Bean
	public class HelloApiStaticFactory {  
	    //工厂方法  
	    public static HelloApi newInstance(String message) {  
		//返回需要的Bean实例  
	        return new HelloImpl2(message);  
	    }  
	} 
静态工程写完了,下面配置bean.xml,注意要指定factory-method
	<!-- 使用静态工厂方法 -->  
	<bean id="bean2" class="com.hello.HelloApiStaticFactory" factory-method="newInstance">  
	     <constructor-arg index="0" value="Hello Spring!"/>  
	</bean> 
       3、使用实例工厂方法实例化Bean,使用这种方式不能指定class属性,此时必须使用factory-bean属性来指定工厂Bean,factory-method属性指定实例化Bean的方法,而且使用实例工厂方法允许指定方法参数,方式和使用构造器方式一样,配置如下:
	public class HelloApiInstanceFactory {  
	   public HelloApi newInstance(String message) {  
		  return new HelloImpl(message);  
	   }  
	}  
	<!-- 1、定义实例工厂Bean -->
	<bean id="beanInstanceFactory" class="com.hello.HelloApiInstanceFactory" />
	<!-- 2、使用实例工厂Bean创建Bean -->
	<bean id="bean3" factory-bean="beanInstanceFactory"
		factory-method="newInstance">
		<constructor-arg index="0" value="Hello Spring!"></constructor-arg>
	</bean>		
       这三种方式只是配置不一样,从获取方式看完全一样,没有任何不同。这也是Spring IoC的魅力,Spring IoC帮你创建Bean,我们只管使用就可以了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值