【SpringDay02之基于注解的配置】

基于注解的配置

从 Spring 2.5 开始就可以使用注解来配置依赖注入。而不是采用 XML 来描述一个 bean 连线,你可以使用相关类,方法或字段声明的注解,将 bean 配置移动到组件类本身。
在 XML 注入之前进行注解注入,因此后者的配置将通过两种方式的属性连线被前者重写。
注解连线在默认情况下在 Spring 容器中不打开。因此,在可以使用基于注解的连线之前,我们将需要在我们的 Spring 配置文件中启用它。所以如果你想在 Spring 应用程序中使用的任何注解,可以考虑到下面的配置文件。一旦被配置后,你就可以开始注解你的代码,表明 Spring 应该自动连接值到属性,方法和构造函数。

<?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">

   <context:annotation-config/>
   <!-- bean definitions go here -->

</beans>
序号分类
1用于创建bean对象
2用于注入数据的
3用于改变作用范围的
4和生命周期相关的
5Spring的新注解

用于创建bean对象

@Component

  • 作用:就相当于配置了一个bean标签
  • 它能出现的位置:类上面
  • 属性:value。含义是指定bean的id。当不写时,它有默认值,默认值是:当前类的短名首字母改小写。
  • 由此衍生的三个注解:
    @Controller:一般用于表现层的注解
    @Service:一般用于业务层
    @Repository:一般用于持久层
    (它们和@Component的作用及属性都一模一样)

用于注入数据

注解作用属性
@Autowired自动按照类型注入,只要有唯一的类型匹配就能注入成功。如果注入的bean在容器中类型不唯一时,它会把变量名称作为bean的id,在容器中查找,找到后也能注入成功。如果没有找到一致的bean的id,则报错
@Qualifier在自动按照类型注入的基础上,再按照bean的id注入。它在给类成员注入数据时不能独立使用。但是在给方法的形参注入数据时,可以独立使用。value:用于指定bean的id
@Resource直接按照bean的id注入name:用于指定bean的id
@Value用于注入基本类型和String类型数据。它可以借助spring的el表达式读取properties文件中的配置value:用于指定要注入的数据

前三个注解都是用于注入其他bean类型的,用于注入基本类型和String类型需要使用Value

下面显示的是使用 @Qualifier 注释的一个示例
Student.java 文件的内容:

package com.tutorialspoint;
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;
   }
}

Profile.java 文件的内容:

package com.tutorialspoint;
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() );
   }
}

MainApp.java 文件的内容:

package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      Profile profile = (Profile) context.getBean("profile");
      profile.printAge();
      profile.printName();
   }
}

考虑下面配置文件 Beans.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">

   <context:annotation-config/>

   <!-- Definition for profile bean -->
   <bean id="profile" class="com.tutorialspoint.Profile">
   </bean>

   <!-- Definition for student1 bean -->
   <bean id="student1" class="com.tutorialspoint.Student">
      <property name="name"  value="Zara" />
      <property name="age"  value="11"/>
   </bean>

   <!-- Definition for student2 bean -->
   <bean id="student2" class="com.tutorialspoint.Student">
      <property name="name"  value="Nuha" />
      <property name="age"  value="2"/>
   </bean>

</beans>

如果你的应用程序一切都正常的话,这将会输出以下消息:

Inside Profile constructor.
Age : 11
Name : Zara

用于改变作用范围的

@Scope

  • 作用:用于改变bean的作用范围。
  • 属性:value:用于指定范围的取值。
    取值和xml中scope属性的取值是一样的。singleton,prototype,request,session globalsession

和生命周期有关的(了解):

@PostConstruct
作用:用于指定初始化方法。
@PreDestroy
作用:用于指定销毁方法

关于Spring注解和XML的选择问题

  • 注解的优势:配置简单,维护方便(我们找到类,就相当于找到了对应的配置)。
  • XML的优势:修改时,不用改源码。不涉及重新编译和部署。
  • Spring管理bean方式的比较:
    在这里插入图片描述

Spring基于Java的配置(纯注解配置)

我们发现,之所以我们现在离不开xml配置文件,是因为我们有一句很关键的配置:

<!-- 告知spring框架在,读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中 -->
	<context:component-scan base-package="com.itheima"></context:component-scan>

如果它要也能用注解配置,那么我们就可以脱离xml文件了。

/**
 * 客户的业务层实现类
 */
@Configuration//表明当前类是一个配置类
@ComponentScan(basePackages = "com.itheima")//配置要扫描的包
public class SpringConfiguration {
}

//那么新的问题又来了,我们如何获取容器呢?
public class Client {
	public static void main(String[] args) {
		//1.获取容器:由于我们已经没有了xml文件,所以再用读取xml方式就不能用了。
		//这时需要指定加载哪个类上的注解
		ApplicationContext ac = 
			new AnnotationConfigApplicationContext(SpringConfiguration.class);
		//2.根据id获取对象
		ICustomerService cs = (ICustomerService) ac.getBean("customerService");
		cs.saveCustomer();
	}
}

新注解说明

@Configuration

  • 作用:用于指定当前类是一个spring配置类,当创建容器时会从该类上加载注解。获取容器时需要使用AnnotationApplicationContext(有@Configuration注解的类.class)。
  • 属性: value:用于指定配置类的字节码

@ComponentScan

  • 作用:用于指定spring在初始化容器时要扫描的包。作用和在spring的xml配置文件中的:<context:component-scan base-package="com.itheima"/>是一样的。
  • 属性:basePackages:用于指定要扫描的包。和该注解中的value属性作用一样。

@PropertySource

  • 作用:用于加载.properties文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到properties配置文件中,就可以使用此注解指定properties配置文件的位置。
  • 属性:value []:用于指定properties文件位置。如果是在类路径下,需要写上classpath:

@Import

  • 作用:用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration注解。当然,写上也没问题。
  • 属性: value[]:用于指定其他配置类的字节码。
  • 示例代码:
@Configuration
@ComponentScan(basePackages = "cn.itcast.spring")
@Import({ Configuration_B.class})
public class Configuration_A {
}

@Configuration
@PropertySource("classpath:info.properties")
public class Configuration_B {

}

@Bean

  • 作用:该注解只能写在方法上,表明使用此方法创建一个对象,并且放入spring容器。它就相当于我们之前在xml配置中介绍的factory-bean和factory-method。

  • 属性:name:给当前@Bean注解方法创建的对象指定一个名称(即bean的id)。

@Configuration 和 @Bean 注解

带有 @Configuration 的注解类表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源。@Bean 注解告诉 Spring,一个带有 @Bean 的注解方法将返回一个对象,该对象应该被注册为在 Spring 应用程序上下文中的 bean(它是把方法的返回值存入spring容器中。该注解有一个属性,name:用于指定bean的id。当不指定时它有默认值,默认值是方法的名称)。最简单可行的 @Configuration 类如下所示:

package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class HelloWorldConfig {
   @Bean //它是把方法的返回值存入spring容器中。该注解有一个属性,name:用于指定bean的id。当不指定时它有默认值,默认值是方法的名称。
   public HelloWorld helloWorld(){
      return new HelloWorld();
   }
}

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

<beans>
   <bean id="helloWorld" class="com.tutorialspoint.HelloWorld" />
</beans>

在这里,带有 @Bean 注解的方法名称作为 bean 的 ID,它创建并返回实际的 bean。你的配置类可以声明多个 @Bean。一旦定义了配置类,你就可以使用 AnnotationConfigApplicationContext 来加载并把他们提供给 Spring 容器,如下所示:

public static void main(String[] args) {
   ApplicationContext ctx = 
   new AnnotationConfigApplicationContext(HelloWorldConfig.class); 
   HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
   helloWorld.setMessage("Hello World!");
   helloWorld.getMessage();
}

你可以加载各种配置类,如下所示:

public static void main(String[] args) {
   AnnotationConfigApplicationContext ctx = 
   new AnnotationConfigApplicationContext();
   ctx.register(AppConfig.class, OtherConfig.class);
   ctx.register(AdditionalConfig.class);
   ctx.refresh();
   MyService myService = ctx.getBean(MyService.class);
   myService.doStuff();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值