1.3-Spring 基于注解的配置

1,从 Spring 2.5 开始就可以使用注解来配置依赖注入
2,关键字<context:annotation-config/>

注解描述
@Required注解应用于 bean 属性的 set 方法
@Autowired注解可以应用到 bean 属性的 set 方法、非 setter 方法、构造函数、属性
@Qualifier通过指定确切的将被连线的 bean,@Autowired 和 @Qualifier 注解可以用来删除混乱
JSR-250 AnnotationsSpring 支持 JSR-250 的基础的注解,其中包括了 @Resource,@PostConstruct 和 @PreDestroy 注解。

@Required

应用于 bean 属性的 set 方法,在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常
它的作用相当于byName

public class Student {
   private Integer age;
   private String name;
   @Required
   public void setAge(Integer age) {
      this.age = age;
   }
   public Integer getAge() {
      return age;
   }
   @Required
   public void setName(String name) {
      this.name = name;
   }
   public String getName() {
      return name;
   }
}

如果只配置了name而没有配置age的话,将会引起BeanInitializationException异常,因为有@Required注解的方法必须在bean中配置指明

<context:annotation-config/>

<bean id="student" class="com.xxx.xxx.Student">
    <property name="name"  value="test1" />
    <property name="age"  value="11"/>
</bean>

@Autowired

对在哪里和如何完成自动连接提供了更多的细微的控制
如果在set方法上使用@Autowired ,那么它的作用相当于byType

import org.springframework.beans.factory.annotation.Autowired;
public class Tes1t{
   private Test2 test2;
   @Autowired
   public void setTest2 ( Test2 test2){
      this.test2= test2;
   }
   public Test2  getTest2 ( ) {
      return test2;
   }
}
<context:annotation-config/>

<bean id="test1" class="com.xxx.xxx.Test1"/>

<bean id="test2" class="com.xxx.xxx.Test2"/>

@Autowired也可以直接配置在属性上,这样做相当于赋值于set方法

import org.springframework.beans.factory.annotation.Autowired;
public class Tes1t{
    @Autowired
    private Test2 test2;

    public Test2  getTest2 ( ) {
      return test2;
    }
}

@Autowired也可以直接配置在构造方法上,这样做当这个类被创建的时候,就会set进构造方法所需要的参数

import org.springframework.beans.factory.annotation.Autowired;
public class Tes1t{
   private Test2 test2;
   @Autowired
   public  Tes1t( Test2 test2){
      this.test2= test2;
   }
   public Test2  getTest2 ( ) {
      return test2;
   }
}

@Autowired 的(required=false)选项
默认情况下是true,类似于@Required,参数是必须传递的。
false的话,则参数可以不传递

@Qualifier 注释

当你创建多个具有相同类型的 bean 时,并且想要用一个属性只为它们其中的一个进行装配,在这种情况下,你可以使用 @Qualifier 注释和 @Autowired 注释通过指定哪一个真正的 bean 将会被装配来消除混乱

public class Student {
   private Integer age;
   private String name;
   public void setAge(Integer age) {
      this.age = age;
   }   
   public Integer getAge() {
      return age;
   }
   public void setName(String name) {
      this.name = name;
   }  
   public String getName() {
      return name;
   }
}

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Profile {
   @Autowired
   @Qualifier("student1")
   private Student student;
   public Profile(){
      System.out.println("Inside Profile constructor." );
   }
   public void printAge() {
      System.out.println("Age : " + student.getAge() );
   }
   public void printName() {
      System.out.println("Name : " + student.getName() );
   }
}

我们的bean中有两个student,我们可以使用Qualifier来指定我们需要的是student1还是student2


   <context:annotation-config/>

   <bean id="profile" class="com.xxx.xxx.Profile">
   </bean>

   <bean id="student1" class="com.xxx.xxx.Student">
      <property name="name"  value="test1" />
      <property name="age"  value="11"/>
   </bean>

   <bean id="student2" class="com.xxx.xxx.Student">
      <property name="name"  value="test2" />
      <property name="age"  value="2"/>
   </bean>

JSR-250 注释

它包括 @PostConstruct, @PreDestroy 和 @Resource 注释
@PostConstruct 和 @PreDestroy 注释:
定义你的bean的生命周期
@Resource 注释:
相当于byName

public class Test{
   private Test2 test2;

   @Resource(name= "testTwo")
   public void setMessage(Test2 test2){
      this.test2= test2;
   }
   public Test2 getTest2 (){
      return test2;
   }
   @PostConstruct
   public void init(){
      System.out.println("Bean is going through init.");
   }
   @PreDestroy
   public void destroy(){
      System.out.println("Bean will destroy now.");
   }
}
<context:annotation-config/>

<bean id="test" class="com.xxx.xxx.Test" init-method="init" destroy-method="destroy">

</bean>
<bean id="testTwo" class="com.xxx.xxx.TestTwo"/>

基于 Java 的配置

@Configuration
带有 @Configuration 的注解类表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源
@Bean
@Bean 注解告诉 Spring,一个带有 @Bean 的注解方法将返回一个对象,该对象应该被注册为在 Spring 应用程序上下文中的 bean

import org.springframework.context.annotation.*;
@Configuration
public class Test{
   @Bean 
   public Test2 test2(){
      return new Test2();
   }
}

上面的代码将等同于下面的 XML 配置:

<beans>
   <bean id="test2" class="com.xxx.xxx.Test2" />
</beans>

解析

ApplicationContext ctx = 
   new AnnotationConfigApplicationContext(Test.class); 

可以加载各种配置类

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
   ctx.register(AppConfig.class, OtherConfig.class);
   ctx.register(AdditionalConfig.class);
   ctx.refresh();
   Test test = ctx.getBean(Test.class);

@Import
允许从另一个配置类中加载 @Bean 定义

@Configuration
public class ConfigA {
   @Bean
   public A a() {
      return new A(); 
   }
}

@Configuration
@Import(ConfigA.class)
public class ConfigB {
   @Bean
   public B a() {
      return new A(); 
   }
}

当实例化上下文时,不需要同时指定 ConfigA.class 和 ConfigB.class,只需要 ConfigB 类

public static void main(String[] args) {
   ApplicationContext ctx = 
   new AnnotationConfigApplicationContext(ConfigB.class);
   A a = ctx.getBean(A.class);
   B b = ctx.getBean(B.class);
}

生命周期回调

public class Foo {
   public void init() {
      // initialization logic
   }
   public void destroy() {
      // destruction logic
   }
}

@Configuration
public class AppConfig {
   @Bean(initMethod = "init", destroyMethod = "destroy" )
   public Foo foo() {
      return new Foo();
   }
}

@Scope 指定 Bean 的范围
默认范围是单实例

@Configuration
public class AppConfig {
   @Bean
   @Scope("prototype")
   public Foo foo() {
      return new Foo();
   }
}

事件处理

Spring 内置事件描述
ContextRefreshedEvent当使用 ConfigurableApplicationContext 接口的 refresh() 方法刷新。ApplicationContext 被初始化或刷新时,该事件也会被发布。
ContextStartedEvent当使用 ConfigurableApplicationContext 接口中的 start() 方法开始
ContextStoppedEvent当使用 ConfigurableApplicationContext 接口中的 stop() 方法停止
ContextClosedEvent当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭
RequestHandledEvent这是一个 web-specific 事件,告诉所有 bean, HTTP 请求已经被服务。

监听上下文事件
一个 bean 应该实现只有一个方法 onApplicationEvent() 的 ApplicationListener 接口

public class Test{
   private String message;
   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;
public class CStartEventHandler 
   implements ApplicationListener<ContextStartedEvent>{
   public void onApplicationEvent(ContextStartedEvent event) {
      System.out.println("ContextStartedEvent Received");
   }
}
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;
public class CStopEventHandler 
   implements ApplicationListener<ContextStoppedEvent>{
   public void onApplicationEvent(ContextStoppedEvent event) {
      System.out.println("ContextStoppedEvent Received");
   }
}
   <bean id="test" class="com.xxx.xxx.Test">
      <property name="message" value="Hello World!"/>
   </bean>

   <bean id="cStartEventHandler" 
         class="com.xxx.xxx.CStartEventHandler"/>

   <bean id="cStopEventHandler" 
         class="com.xxx.xxx.CStopEventHandler"/>
 public static void main(String[] args) {
      ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      context.start();
      Testobj = (Test) context.getBean("test");
      obj.getMessage();
      context.stop();
   }

自定义事件

import org.springframework.context.ApplicationEvent;
public class CustomEvent extends ApplicationEvent{ 
   public CustomEvent(Object source) {
      super(source);
   }
   public String toString(){
      return "My Custom Event";
   }
}
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
public class CustomEventPublisher 
   implements ApplicationEventPublisherAware {
   private ApplicationEventPublisher publisher;
   public void setApplicationEventPublisher
              (ApplicationEventPublisher publisher){
      this.publisher = publisher;
   }
   public void publish() {
      CustomEvent ce = new CustomEvent(this);
      publisher.publishEvent(ce);
   }
}
import org.springframework.context.ApplicationListener;
public class CustomEventHandler 
   implements ApplicationListener<CustomEvent>{
   public void onApplicationEvent(CustomEvent event) {
      System.out.println(event.toString());
   }
}
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      ConfigurableApplicationContext context = 
      new ClassPathXmlApplicationContext("Beans.xml");    
      CustomEventPublisher cvp = 
      (CustomEventPublisher) context.getBean("customEventPublisher");
      cvp.publish();  
      cvp.publish();
   }
}
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id="customEventHandler" 
      class="com.xxx.xxx.CustomEventHandler"/>

   <bean id="customEventPublisher" 
      class="com.xxx.xxx.CustomEventPublisher"/>

</beans>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值