zoukankan      html  css  js  c++  java
  • Spring之IoC

      

          上面的图是Spring的主要模块示意图,IoC属于Spring的Core模块。

           使用Spring中各模块的功能时,首先要在xml中引入模块对应的命令空间。

          

       1.IoC基本概念

          IoC控制翻转,指的是对象的创建及对象生命周期的控制不再由程序本身完成,而是由IoC容器来完成,可以是Spring,也可是EJB。

          由程序区创建对象,例如如下的代码:  

      PersonDao dao = new PersonDaoBean();

          这样dao对象是依赖于代码本身的。IoC是指对象的创建通过Spring中创建,可以基于构造方法或set方法等,将dao的创建交给Spring,代码不再需要去new这样一个对象。

          DI依赖注入,就是在运行期,由外部对象注入到组件中,常常和IoC是一起存在的。

       2.Spring中的bean

          Spring是通过bean来管理对象及实现Ioc的。

      下面的是一个Java Bean的实例: 

    public class SpringBeanTest {
        private Action action;
        private String beanName;
        
        public String getBeanName() {
            return beanName;
        }
        public void setBeanName(String name) {
            this.beanName = name;
        }
        public Action getAction() {
            return action;
        }
        public void setAction(Action action) {
            this.action = action;
        }
        
        private void start(){
            System.out.println("get resource for database");
        }
        
        private void destroy(){
            System.out.println("release resource for database");
        }
        
        public void actionTest(){
            System.out.println(action.execute("Kare Smith"));
        }
    }

      为了管理这个bean,我们需要在一个xml文件中配置这个bean,以便Spring可以知道这个bean的存在并对它进行控制。

    <?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
    ">
        <bean id = "beanTest" class = "qs.SpringBeanTest" scope="singleton" init-method = "start" destroy-method = "destroy">
            <!-- 指定属性参数 -->
           <property name = "beanName">
              <value>hello</value>
           </property>
            <!-- 注入其他的bean -->
            <property name = "action">
              <ref bean ="upper"/>
           </property>
        </bean>
            
           <bean id = "upper" class = "qs.UpperAction" scope="singleton"/>
    </beans>

         上面的JavaBean中还用到了一个类UpperAction,其代码如下: 

    public class UpperAction implements Action {
        public String execute(String str) {
            //return (getMessage() + "," + str).toUpperCase() + " in upperAction";
            return str.toUpperCase() + " in upperAction";
        }
    }

      下面是对xml中bean的配置参数的解释:

      bean的id属性在整个容器中时唯一的,这个是要注意的。name属性和id属性的不同点是,name属性中可以包含特殊字符,正常情况下还是应该使用id属性。

          bean的作用域;singleton,prototype,还有对应于web的request,session,global session(application)。默认的是singleton,这是需要注意的,处理数据时bean使用默认的singleton是会出问题的。singleton的作用范围是Spring容器,在Spring容器之外是不能保证的。

         

       singleton时Spring容器初始化时会初始bean,检查错误。prototype时getBean时才会去初始化对象。

         lazy-init ="true",大体积且不一定会用到的bean适用,lazy-init尽量不使用。

         bean的init-method方法用于打开,准备好程序所需资源。destroy-method用于资源的释放,需要调用AbstractApplicationContext的close方法。init-method和destroy-method都可以被Spring容器动态地调用。 

      

      下面是对这个bean的测试,看看Spring容器是否能够很好地管理这个bean。

    public class SpringBeanTestTest2 {
        private ApplicationContext ctx;
         private SpringBeanTest beanTest;
        @Before
        public void setUp() throws Exception {
            ctx = new ClassPathXmlApplicationContext("bean.xml");
        }
    
        @After
        public void tearDown() throws Exception {
        }
    
        @Test
        public void test() {
            beanTest = (SpringBeanTest) ctx.getBean("beanTest");
            beanTest.actionTest();
        }
    
    }

      FileSystemXmlApplicationContext需要指定文件路径,适用性不强。ClassPathXmlApplicationContext会在类路径包括jar包中寻找xml文件,XmlWebApplicationContext用于读取web应用的xml文件并装载。

      更为完善的测试代码应该如下: 

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("/bean.xml")
    public class SpringBeanTestTest {
    
        @Autowired
        @Qualifier("beanTest")
        private SpringBeanTest beanTest;
        @Test
        public void test() {
            beanTest.actionTest();
        }
    
    }

       3.Spring中的注入

       Spring中的注入分为基本类型的注入,如int,String等和对象的注入。基本类型的注入用的是value属性,对象的注入用的是ref属性。

         Spring中的注入可以有三种方式:构造器注入,set方法注入,注解方式注入。

       再看一个java bean的例子:

    public class LowerAction {
        
        private String message;
        private List<Integer> testlist;    
        private String [][] arrays;
        private Map<Integer, String> maps;
        private Action action;
        
        public Action getAction() {
            return action;
        }
        public void setAction(Action action) {
            this.action = action;
        }
        public Map<Integer, String> getMaps() {
            return maps;
        }
        public void setMaps(Map<Integer, String> maps) {
            this.maps = maps;
        }
        public String[][] getArrays() {
            return arrays;
        }
        public void setArrays(String[][] arrays) {
            this.arrays = arrays;
        }
        public List<Integer> getTestlist() {
            return testlist;
        }
        public void setTestlist(List<Integer> testlist) {
            this.testlist = testlist;
        }
        public String getMessage() {
            return message;
        }
        //java bean要求有一个无参的构造方法
        public LowerAction(){
        }
        
        public LowerAction(String arg){
            System.out.println(arg);
        }
        
        public void setMessage(String message) {
            this.message = message;
        }
    
        @Override
        public String execute(String str) {
            return (getMessage() + "," + str).toLowerCase() + ", list is" + getTestlist() + 
                    ",arrays:" + arrays[1][1] + ",maps:" + maps.get(new Integer(1)) + "actions:" + action.execute("muu");
        }
    }

      在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
    ">
        
        <bean id = "theAction" class = "qs.LowerAction" scope="singleton" >
           <!-- 指定属性参数 -->
           <property name = "message">
              <value>hello</value>
           </property>
            <!-- 注入其他的bean -->
            <property name = "action">
              <ref bean ="upper"/>
           </property>
           <!-- 指定构造器参数 -->
           <constructor-arg index = "0" value ="constructor test"/>
           <!-- 注入集合 -->
           <property name = "testlist">
                 <list value-type = "java.lang.Integer">
                  <value>1</value>
                  <value>2</value>
                  <value>3</value>
              </list>
           </property>
            <!-- 注入数组 -->
           <property name = "arrays">
                 <array>
                     <array><value>1</value><value>2</value></array>
                     <array><value>3</value><value>4</value></array>
                 </array>
           </property>
           <!-- 注入字典 -->
           <property name = "maps">
                 <map key-type = "java.lang.Integer" value-type = "java.lang.String">
                     <entry key ="1" value ="2"/>
                 </map>
           </property>
         </bean>
    
    </beans>

     4.自动装配及自动检测

      从上面可以看到,通过xml对bean的属性及引用进行装配,如果bean的数量很多,xml文件将会很大,虽然可以将xml文件分成多份,但依然难以维护。自动装配及自动检测就是为了减少xml中的配置信息。

      自动装配autowiring,减少property属性和constructor-arg属性。
      自动检测autodiscovery,让Spring识别哪些类需要被配置为bean,减少了bean属性。

         4.1基于XML的自动装配

      自动装配分为XML和注解2中方式。基于注解的支持以下注解:@Autowired,@Inject,@Resource。

          

           先看基于XML的自动装配,可以有效地减少xml中的property属性和constructor-arg属性。

          

          

      id为kenny的bean使用了byName的自动装配方式,com.spriginaction.springidol.Instrumentalist类中的:

           private Instrument instrument;       

           instrument在使用时会被自动装配为Saxophone。

          

            如果Instrument接口存在多个子类,则byType的自动装配将会失败。

           

      

         4.2基于注解的自动装配

           可以看出基于XML的自动装配还不是很简便,基于注解的自动装配会极大地简化配置工作, 下面是使用注解自动装配的介绍:

           基于注解的支持以下注解:@Autowired,@Inject,@Resource。
      @Autowired(required = "false"),不是必须注入的
           

      @Autowired
      @Autowired @Qualifier("guitar")指定注入bean id为guitar的bean。接口被多个类实现,注入接口时就需要。

           
      @Value注入String和其他基本类型的属性。

           @Autowired默认是按类型装配,@Resource默认是按名称进行装配,名称找不到时再按类型装配。

           @Resource在JDK1.6中已支持,是通用的,@Autowired是Spring自己的注解。

           可以标注在变量上(可以不需要set方法)或者set方法上。

          

           

           

     4.3 自动检测bean

      自动检测bean
      @Component,通用组件  @Component("add") 显示的指明bean的id
      @Controller Spring MVC 的Controller,struts的action
      @Repository  数据仓库,DAO组件
      @Service  业务层,定义为服务

           

           @Component  @Scope("prototype")

           @PostConstruct用于标识bean的init方法

           @PreDestroy用于destroy方法

           自动扫描一般制定一个包,去扫描这个包及子包中的bean。也可以加上过滤器,使得扫描条件更为精确。

          

    include-filter将和component-scan的条件取交集,自动扫描Instrument的子类。

          

      include-filter可以和exclude-filter配合使用。

          

  • 相关阅读:
    ListCtr 每一行都加上选择框
    VC中MFC check box的用法
    第二章 掌握C++(2)C++的特性(上)
    第二章 掌握C++(1)从结构到类
    道路横断面设计
    第一章 Windows程序内部运行机制(5)动手编写一个Windows程序
    第一章 Windows程序内部运行机制(4)WinMain函数(续)
    将div旋转任意角度
    地址栏图标修改
    script 错误
  • 原文地址:https://www.cnblogs.com/lnlvinso/p/3997268.html
Copyright © 2011-2022 走看看