Spring入门篇二(2)

来源:互联网 发布:消息队列java 编辑:程序博客网 时间:2024/06/11 21:55

Bean的定义及作用域的注解实现

·Bean管理的注解实现及例子
·Classpath扫描与组件管理
·从Spring3.0开始,Spring JavaConfig项目提供了很多特性,包括使用java而不是xml定义bean,比如@Configuration,@Bean,@Import,@DependsOn
·Component是一个通用注解,可用于任何bean
·@Repository(通常用于注解DAO类,即永久层),@Service(通常用于注解Service类,即服务层),@Controller(通常用于Controller类,及控制层MVC)是更有针对性的注解

元注解
·许多Spring提供的注解可以作为自己的代码,即“元数据注解”,元注解是一个简单的注解,可以应用到另一个注解
·除了value(),元注解还可以有其它的属性,允许定制。


·类的自动检测与注册Bean
·Spring可以自动检测类并注册Bean得到ApplicationContext中
·为了能够检测这些类并注册相应的Bean,需要下面内容
<beans xmlns=”http://www.springframeword.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/xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd”>

<context:component-scan base-package=”org.example”/>
<beans>
·<context:component-scan包含<context:annotation-cofig/>,通常在使用前者后,不用再使用后者
·AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor也会被包含进来


·<context:annotation-cofig/>
·通过在基于XML的Spring配置如下标签(请注意包含上下文命名空间)
<beans xmlns=”http://www.springframeword.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/xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd”>

<context:annotation-config/>
<beans>
·<context:annotation-config/>仅会查找在同一个applicationContext中的bean注解

使用过滤器进行自定义扫描
·默认情况下,类被自动发现并注册bean的条件是:使用@Component,@Repository,@Service,@Controller注解或者使用@Component的自定义注解
·可以通过过滤器修改上面的行为,如:下面例子的XML配置忽略所有的@Repository注解并用Stub代替
<beans>
<context:component-scan base-package=”org.example”>
<context:include-filter type=”regex”
expression=”.*Stub.*Repository”/>
<context:exclude-filter type=”annotation”
expression=”org.springframework.stereotype.Repository/>
</context component-scan>
</beans>
`还可以使用use-default-filter=”false” 禁止自动发现与注册


·@Component,@Repository,@Service,@Controller

定义Bean
·扫描过程中组件被自动检测,那么Bean名称是由BeanNameGenertor生成的(以类名为基础,第一个字符小写)(@Component,@Repository,@Service,@Controller都会有个name属性用于显式设置Bean Name)
·可自定义bean命名策略,实现BeanNameGenertor接口,并一定要包含一个无参数构造器
<beans>
<context:component-scan base-package=”org.example”
name-genertor=”org.example.MyNameGenertor”/>
</beans>

作用域(Scope)
·通常情况下自动查找的Spring 组件,其scope是singleton(在一个IOC容器中是单例的),Spring2.5提供了一个表示scope的注解@Scope
·也可以自定义scope策略,实现ScopeMetadataResolver接口并提供一个无参构造器
<beans>
<context:component-scan base-package=”org.example”
scope-resovler=”org.example.MyScopeResolver”/>
</beans>

代理方式
·可以使用scoped-proxy属性指定代理,有三个值可选:no,interface,targetClass
<beans>
<context:component-scan base-package=”org.example”
Scoped-proxy=”interface”/>
</beans>

代码示例:
<?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.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context.xsd"> 
 
 <context:component-scan base-package="com.hushi.springdemo"></context:component-scan>
</beans>

//@Component("bean")
@Scope("prototype")
@Component()
public class BeanAnnotation {

// public void say(String s){
//  System.out.println("BeanAnnotation:"+s);
// }
 
 public void showHashCode(){
  System.out.println(this.hashCode());
 }
}

public class AnnotationTest extends JUnitTestBase {

 public AnnotationTest() {
  super("applicationContext.xml");
  // TODO Auto-generated constructor stub
 }

// @Test
// public void testSay() {
//  BeanAnnotation ba = (BeanAnnotation) super.getBean("bean");
//  ba.say("This is a annotation test");
// }
 
 @Test
 public void testShow(){
  BeanAnnotation ba = (BeanAnnotation) super.getBean("beanAnnotation");
  ba.showHashCode();
  
  ba = (BeanAnnotation) super.getBean("beanAnnotation");
  ba.showHashCode();
 }

}

public class JUnitTestBase {

 private ClassPathXmlApplicationContext context;
 private String xml;
 public JUnitTestBase(String xml) {
  this.xml = xml;
 }
 public Object getBean(String beanName) {
  return context.getBean(beanName);
 }
 
 @After
 public void after(){
  context.destroy();
 }
 @Before
 public void before(){
  context = new ClassPathXmlApplicationContext(xml);
  context.start();
 }
}


@Required(不常用)
·该注解适用于bean属性的setter方法
·这个注解仅仅表示,受影响的bean属性必须在配置时被填充,通过在bean定义或通过自动装配一个明确的属性值

@Autowired(常用)
·注解为“传统的”setter方法
·可用于构造器或成员变量
·默认情况下,如果找不到合适的bean将会导致autowiring失败抛出异常,可以通过下面的方式避免:@Autowired(required=false)
·每个类只能有一个构造器被标记为required=true
public class ServiceInterfaceImpl implements ServiceInterface {
 
 @Autowired
 private DaoInterface dao;
 
 @Autowired
 public void setDao(DaoInterface dao){
  this.dao = dao;
 }
 
 @Autowired
 public ServiceInterfaceImpl(DaoInterface dao){
  this.dao = dao;
 }
 public void save(String s) {
  // TODO Auto-generated method stub
  System.out.println("Service接收到参数:"+s);
  dao.save(s);
 }

public class DaoInterfaceImpl implements DaoInterface {

 public void save(String s) {
  // TODO Auto-generated method stub
  System.out.println("Dao接收到Service传来的参数:"+s);
 }
}
public class AnnotationTest extends JUnitTestBase {

 public AnnotationTest() {
  super("applicationContext.xml");
  // TODO Auto-generated constructor stub
 }

 @Test
 public void test(){
  ServiceInterfaceImpl service = (ServiceInterfaceImpl) super.getBean("serviceInterfaceImpl");
  service.save("test---------");
 }
·@Autowired的必要属性,建议使用@required注解
·可以使用其来注解那些总所周知的解析依赖性接口,比如:BeanFactory,ApplicationContext,Environment,ResourceLoader,ApplicationEventPublisher,and MessageSource
·可以通过添加注解给需要该类型的数组的字段或方法,以提供ApplicationContext中的所有特定类型的bean
private Set<MovieCatalog> movieCatalog;

@Autowired
public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs){
This.movieCatalogs = movieCatalogs;
}
applicationContext中的所有MovieCatalog bean或其子类bean都会被装配到该方法中
代码示例:
@Component
public interface BeanInterface {

}
@Component
public class BeanOne implements BeanInterface {

}
@Component
public class BeanTwo implements BeanInterface {

}
@Component
public class BeanInvoker {

 @Autowired
 private List<BeanInterface> beanList;
 
@Autowired
 private Map<String,BeanInterface> map;

 @Autowired
 public void setBeanList(List<BeanInterface> beanList){
  this.beanList = beanList;
 }
 
@Autowired
 public void setMap(Map<String,BeanInterface> map){
  this.map = map;
 }

 public void showName(){
  if(this.beanList != null && beanList.size() != 0){
   for(BeanInterface list : beanList){
    System.out.println(list.getClass().getName());
   }
  }

if(this.map != null && map.size() != 0){
   for(Entry<String, BeanInterface> entry : map.entrySet()){
    System.out.println(entry.getKey()+"   "+entry.getValue().getClass().getName());
   }
  }
 }
}

public class AnnotationTest extends JUnitTestBase {

 public AnnotationTest() {
  super("applicationContext.xml");
  // TODO Auto-generated constructor stub
 }

 @Test
 public void test(){
  BeanInvoker b = (BeanInvoker) super.getBean("beanInvoker");
  b.showName();
 }
·可以用于自动装配key为String的Map
Key为bean的id,value为对象

·如果希望数组有序,可以让bean实现org.springframework.core.Ordered接口或使用的@Order注解bean,值为整型,对map无效
·Autowired是有Spring BeanPostProcessor处理的,所以不能在自己的BeanPostProcessor类型应用这些注解,这些类型必须通过XML或者Spring的@Bean注解加载


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

原创粉丝点击