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

 

posted @ 2017-04-19 17:58  charles999  阅读(158)  评论(0编辑  收藏  举报