zoukankan      html  css  js  c++  java
  • Spring_3

    转载请注明出处:http://www.cnblogs.com/JsonShare

    Spring学习(8)--- @Autowired注解(一)

     
    • 可以将@Autowired注解为“传统”的setter方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package com.mypackage;
     
    import org.springframework.beans.factory.annotation.Autowired;
     
    public class SimpleMovieLister {
        private MovieFinder movieFinder;
     
        @Autowired
        public void setMovieFinder(MovieFinder movieFinder) {
            this.movieFinder = movieFinder;
        }
         
        //.....
    }
    •  可用于构造器或成员变量
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package com.mypackage;
     
    import org.springframework.beans.factory.annotation.Autowired;
     
    public class SimpleMovieLister {
         
        @Autowired
        private BeanAnnotation beanAnnotation;
         
        private MovieFinder movieFinder;
     
        @Autowired
        public void setMovieFinder(MovieFinder movieFinder) {
            this.movieFinder = movieFinder;
        }
         
        //.....
    }
    •  默认情况下,如果因找不到合适的bean将会导致autowiring失败抛出异常,可以通过下面的方式避免
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package com.mypackage;
     
    import org.springframework.beans.factory.annotation.Autowired;
     
    public class SimpleMovieLister {
        private MovieFinder movieFinder;
     
        @Autowired(required=false)
        public void setMovieFinder(MovieFinder movieFinder) {
            this.movieFinder = movieFinder;
        }
         
        //.....
    }
    •  每个类只能有一个构造器被标记为required=true
    • @Autowired的必要属性,建议用@Required注解

     例子:

    先新建两个接口(InjectionService、InjectionDAO),及实现类

    1
    2
    3
    4
    5
    6
    package com.mypackage;
     
    public interface InjectionDAO {
         
        public void save(String args);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.mypackage;
     
    import org.springframework.stereotype.Repository;
     
    @Repository
    public class InjectionDAOImpl implements InjectionDAO {
     
        public void save(String args) {
            //模拟数据库操作
            System.out.println("DAO保存数据:" + args);
        }
     
    }
    1
    2
    3
    4
    5
    6
    package com.mypackage;
     
    public interface InjectionService {
     
        public void save(String args);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package com.mypackage;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
     
    @Service
    public class InjectionServiceImpl implements InjectionService{
     
        @Autowired
        private InjectionDAO injectionDAO;
     
        public void save(String s){
            //模拟业务操作
            System.out.println("Service接收参数:"+s);
            s=s+":"+this.hashCode();
            injectionDAO.save(s);
        }
    }

    XML配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?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-4.1.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-4.1.xsd">
             
            <context:component-scan base-package="com.mypackage">
            </context:component-scan>   
    </beans>

      单元测试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package com.mypackage;
     
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
     
     
    public class UnitTest {
         
        @Test
        public void testAutoWired(){
            ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-beanannotation.xml"); 
            InjectionService service=(InjectionService)context.getBean("injectionServiceImpl");
            service.save("this is autowired");;
             
        }
    }

     结果:

    复制代码
    2015-7-6 15:52:26 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1342a80d: startup date [Mon Jul 06 15:52:26 CST 2015]; root of context hierarchy
    2015-7-6 15:52:26 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [spring-beanannotation.xml]
    Service接收参数:this is autowired
    DAO保存数据:this is autowired:1811560891
    复制代码

    @Autowired也可应用于构造器

    修改InjectionServiceImpl实现类(添加setter)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    package com.mypackage;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
     
    @Service
    public class InjectionServiceImpl implements InjectionService{
         
        private InjectionDAO injectionDAO;
         
        @Autowired
        public void setInjectionDAO(InjectionDAO injectionDAO) {
            this.injectionDAO = injectionDAO;
        }
     
        public void save(String s){
            //模拟业务操作
            System.out.println("Service接收参数:"+s);
            s=s+":"+this.hashCode();
            injectionDAO.save(s);
        }
    }

     测试结果:

    复制代码
    2015-7-6 15:55:23 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@939b78e: startup date [Mon Jul 06 15:55:23 CST 2015]; root of context hierarchy
    2015-7-6 15:55:23 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [spring-beanannotation.xml]
    Service接收参数:this is autowired
    DAO保存数据:this is autowired:1860295362
    复制代码

     Spring学习(9)--- @Autowired注解(二)

     
    • 可以使用@Autowired注解那些众所周知的解析依赖性接口,比如:BeanFactory,ApplicationContext,Environment,ResourceLoader,ApplicationEventPublisher,MessageSource
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package com.mypackage;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
     
    public class MovieRecommender {
     
        @Autowired
        private ApplicationContext context;
         
        public MovieRecommender(){
        }
         
        //...
    }
    •  可以通过添加注解给需要该类型的数组的字段和方法,以提供ApplicationContext中的所有特定类型的bean
    1
    2
    3
    4
    5
    6
    private Set<MovieCatalog> movieCatalogs;
     
    @Autowired
    public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
        this.movieCatalogs = movieCatalogs;
    }
    • 可以用于装配key为String的Map
    1
    2
    3
    4
    5
    6
    private Map<String , MovieCatalog>  movieCatalog;
     
    @Autowired
    public void setMovieCatalog(Map<String, MovieCatalog> movieCatalog) {
        this.movieCatalog = movieCatalog;
    }
    • 如果希望数组有序,可以让bean实现org.springframework.core.Ordered接口或使用的@Order注解
    • @Autowired是由Spring BeanPostProcessor处理的,所以不能在自己的BeanPostProcessor或BeanFactoryPostProcessor类型应用这些注解,这些类型必须通过XML或者Spring的@Bean注解加载

    数组及Map的自动注入——例子:

      !!!此方法也可以查看到某个接口在ioc容器里有多少个实现类的bean被加载

    先定义一个BeanInterface接口

    1
    2
    3
    4
    5
    package com.multibean;
     
    public interface BeanInterface {
     
    }

    在定义两个实现类

    1
    2
    3
    4
    5
    6
    7
    8
    package com.multibean;
     
    import org.springframework.stereotype.Component;
     
    @Component
    public class BeanInterfaceImpl implements BeanInterface {
     
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    package com.multibean;
     
    import org.springframework.stereotype.Component;
     
    @Component
    public class BeanInterface2Impl implements BeanInterface{
     
         
    }

    定义BeanInvoker实现数组和Map

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    package com.multibean;
     
    import java.util.*;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
     
    @Component
    public class BeanInvoker {
     
        @Autowired
        private List<BeanInterface> list;
         
        @Autowired
        private Map<String,BeanInterface> map;
         
        public void say(){
            if(null != list){
                System.out.println("list...");
                for(BeanInterface bean:list){
                    System.out.println(bean.getClass().getName());
                }
            }else{
                System.out.println("List<BeanInterface> list is null.");
            }
             
            if(null != map && 0 != map.size()){
                System.out.println("map...");
                for(Map.Entry<String,BeanInterface> entry:map.entrySet()){
                    System.out.println(entry.getKey()+"-----"+entry.getValue().getClass().getName());
                }
            }else{
                System.out.println("Map<String,BeanInterface> map is null.");
            }
        }
         
    }

    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-4.1.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-4.1.xsd">
             
            <context:component-scan base-package="com.multibean">
            </context:component-scan>   
    </beans>
    复制代码

    单元测试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package com.multibean;
     
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
     
    public class UnitTest {
     
        @Test
        public void test(){
            ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-beansnnotation.xml");
            BeanInvoker beanInvoker = (BeanInvoker)context.getBean("beanInvoker");
            beanInvoker.say();
        }
    }

    结果:

    复制代码
    七月 06, 2015 10:46:41 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@32482417: startup date [Mon Jul 06 22:46:41 CST 2015]; root of context hierarchy
    七月 06, 2015 10:46:41 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [spring-beansnnotation.xml]
    list...
    com.multibean.BeanInterface2Impl
    com.multibean.BeanInterfaceImpl
    map...
    beanInterface2Impl-----com.multibean.BeanInterface2Impl
    beanInterfaceImpl-----com.multibean.BeanInterfaceImpl
    复制代码

    @Order注解----例子:

    改造一下两个实现类,加上@Order注解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package com.multibean;
     
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
     
    @Order(value = 1)
    @Component
    public class BeanInterfaceImpl implements BeanInterface {
     
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package com.multibean;
     
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
     
    @Order(value = 2)
    @Component
    public class BeanInterface2Impl implements BeanInterface{
     
         
    }

    测试同上

    结果:

    复制代码
    七月 06, 2015 10:58:58 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1e397bcb: startup date [Mon Jul 06 22:58:58 CST 2015]; root of context hierarchy
    七月 06, 2015 10:58:58 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [spring-beansnnotation.xml]
    list...
    com.multibean.BeanInterfaceImpl
    com.multibean.BeanInterface2Impl
    map...
    beanInterface2Impl-----com.multibean.BeanInterface2Impl
    beanInterfaceImpl-----com.multibean.BeanInterfaceImpl
    复制代码

     PS:@Order只针对数组,对于map无效

    Spring学习(10)--- @Qualifier注解

     
    • 按类型自动装配可能多个bean实例的情况,可以使用Spring的@Qualifier注解缩小范围(或指定唯一),也可以指定单独的构造器参数或方法参数
    • 可用于注解集合类型变量

    例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package com.mypackage;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
     
    public class MovieRecommender {
     
        @Autowired
        @Qualifier("main")
        private MovieCatalog movieCatalog;
         
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.mypackage;
     
    import org.springframework.beans.factory.annotation.Qualifier;
     
    public class MovieRecommender {
     
        private MovieCatalog movieCatalog;
     
        public void prepare(@Qualifier("main")MovieCatalog movieCatalog){
            this.movieCatalog=movieCatalog;
        }
         
    }

    PS:应用于构造器的方法比较常用

    • XML文件中使用qualifier:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <?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-4.1.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-4.1.xsd">
              
            <context:component-scan base-package="com.multibean">
            </context:component-scan>  
             
            <bean class="com.mypackage.MovieCatalog">
                <qualifier value="main"></qualifier>
            </bean>
             
            <bean class="com.mypackage.MovieCatalog">
                <qualifier value="action"></qualifier>
            </bean>
    </beans>
    • 如果通过名字进行注解注入,主要使用的不是@Autowired(即使在技术上能够通过@Qualifier指定bean的名称),替代方式是使用JSR-250@Resource注解,它通过其独特的名称来定义来识别特定的目标(这是一个与所声明的类型是无关的匹配过程)
    • 因语义差异,集合或Map类型的bean无法通过@Autowired来注入,因为没有类型匹配到这样的bean,为这些bean使用@Resource注解,通过唯一名称引用集合或Map的bean
    • @Autowired适用于fields,constructors,multi-argument method这些允许在参数级别使用@Qualifier注解缩小范围的情况
    • @Resource适用于成员变量,只有一个参数的setter方法,所以在目标是构造器或者一个多参数方法时,最好的方式是使用@Qualifier

    例子:

    先定义一个BeanInterface接口

    1
    2
    3
    4
    5
    package com.multibean;
     
    public interface BeanInterface {
     
    }

    在定义两个实现类

    1
    2
    3
    4
    5
    6
    7
    8
    package com.multibean;
     
    import org.springframework.stereotype.Component;
     
    @Component
    public class BeanInterfaceImpl implements BeanInterface {
     
    }

      

    1
    2
    3
    4
    5
    6
    7
    8
    package com.multibean;
     
    import org.springframework.stereotype.Component;
     
    @Component
    public class BeanInterface2Impl implements BeanInterface {
     
    }

    定义BeanInvoker实现@Qualifier指定bean

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    package com.multibean;
     
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Component;
     
    @Component
    public class BeanInvoker {
     
        @Autowired
        @Qualifier("beanInterfaceImpl")
        private BeanInterface beanInterface;
         
        public void say(){
             
            if(null != beanInterface){
                System.out.println(beanInterface.getClass().getName());
            }else{
                System.out.println("BeanInterface is null.");
            }
             
        }
         
    }

    单元测试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package com.multibean;
     
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
     
    public class UnitTest {
     
        @Test
        public void test(){
            ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-beansnnotation.xml");
            BeanInvoker beanInvoker = (BeanInvoker)context.getBean("beanInvoker");
            beanInvoker.say();
        }
    }

    结果:

    七月 06, 2015 11:41:38 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1e397bcb: startup date [Mon Jul 06 23:41:38 CST 2015]; root of context hierarchy
    七月 06, 2015 11:41:38 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [spring-beansnnotation.xml]
    com.multibean.BeanInterfaceImpl

    修改BeanInvoker

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    package com.multibean;
     
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Component;
     
    @Component
    public class BeanInvoker {
     
        @Autowired
        @Qualifier("beanInterface2Impl")
        private BeanInterface beanInterface;
         
        public void say(){
             
            if(null != beanInterface){
                System.out.println(beanInterface.getClass().getName());
            }else{
                System.out.println("BeanInterface is null.");
            }
             
        }
         
    }

    结果:

    七月 06, 2015 11:43:38 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1e397bcb: startup date [Mon Jul 06 23:43:38 CST 2015]; root of context hierarchy
    七月 06, 2015 11:43:38 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [spring-beansnnotation.xml]
    com.multibean.BeanInterface2Impl
  • 相关阅读:
    基于Docker搭建分布式消息队列Kafka
    [转]JAVA 开发环境设置(简单易懂)
    微信分享地址参数记录(出于防止微信刷票而产生的学习记录)
    万网开启二级站点【原创】
    PHP
    [转]什么是RSS
    html页面缓存(浏览器)
    [从jQuery看JavaScript]-匿名函数与闭包(Anonymous Function and Closure)【转】
    Jquery中$.get(),$.post(),$.ajax(),$.getJSON(),$.getScript(),$.load()的用法总结【转】
    JQuery中$.load()方法的用法和分析【转】
  • 原文地址:https://www.cnblogs.com/charles999/p/6639695.html
Copyright © 2011-2022 走看看