Spring-注解&Java容器配置

注解容器配置

在之前的学习中,我们的Bean需要在ApplicationCentext.xml文件中配置,如果Bean很多,就需要写大量的xml文件,既费力又难于维护。利用注解开发就不需要在xml文件中配置Bean了,Spring会自动扫描和装配这些Bean,所以接下来要学习的就是如何利用注解提高开发效率。

装配类的注解

注解的介绍

在Spring中,作用域类的注解是@Component,该注解用于将一个普通类标识为Spring Bean类,它还有三个衍生的注解,目的适用于区分各层级。当使用了注解,就相当于将这个类交由Spring管理l。

衍生注解:

  1. 数据访问层(DAO):@Respository,标识一个持久化层组件。
  2. 业务逻辑层(Service):@Service,标识一个业务逻辑层组件。
  3. 控制层(MVC):@Controller,标识一个表述层控制器组件。

这三个衍生的注解功能都与@Component,目的只是为了表示不同层级,所以都用一个也没有关系。

注解的使用

配置注解可以方便我们梳理逻辑,并且提高效率,使用注解非常简单:

  1. 在实体类上通过注解进行标识;
  2. 将实体类所在的包配置扫描;
  3. 测试。

所以我们需要三个文件:

  1. 实体类:User
  2. xml配置文件:ApplicationContext.xml
  3. 测试类:MyTest
// 等价于<bean id="user" class="POJO.User"/>
@Component
public class User {
    
    //@Value:属性注入
    @Value("张三")
    public String name;
    
}
<!--将User所属的包配置扫描-->
<context:component-scan base-package="POJO"/>
//测试
@org.junit.Test
    public void TestUser(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    User user = applicationContext.getBean("user", User.class);
    System.out.println(user.name);
}

/**
* 输出:
*张三
*/

装配Bean的注解

注解的介绍

参考:Spring-Bean自动装配(后半部分)

@Autowired:根据ByType自动装配,添加@Qualifier则可以再根据ByName自动装配;可用于为类的属性、构造方法、方法进行注值。

@Qualifier:只能搭配@Autowired使用,不能单独使用。

@Resource:默认通过ByName的方法实现装配,如果找不到名字,再通过ByType实现装配(常用)。

@Resource的作用相当于@Autowired,均可标注在字段或属性的setter方法上。

其他注解

@Scope注解用于指定作用域:

  1. singleton(单例模式):默认的,Spring会采用单例模式创建这个对象。关闭工厂 ,所有的对象都会销毁。
  2. prototype(多例模式):关闭工厂 ,所有的对象不会销毁。内部的垃圾回收机制会回收。
@Controller("user")
@Scope("prototype")
public class User {
   @Value("张三")
   public String name;
}

@value:利用该注解注入属性,也可以使用在set方法上。

// 等价于<bean id="user" class="POJO.User"/>
@Component
public class User {
    // 等价于配置文件中 <property name="name" value="张三"/>
    @Value("张三")
    public String name;
}

注解容器配置小结

通过配置注解再在xml文件中配置扫描,就不需要像之前在xml中配置Bean了。

如果配置了注解,不配置扫描等于无效注解。

Java容器配置

Java 配置支持的核心就是@Configuration 类、@Bean方法(方法级别的注释)。

@Configuration是类级别的注解,表明一对象是bean定义的来源。@Configuration类通过@Bean方法声明 bean 。@Bean对@Configuration类方法的调用也可用于定义 bean 间的依赖关系。

配置类主要使用 @Bean 注解的方法来为 Spring 的 IoC 容器管理的对象定义实例、配置和初始化逻辑。

@Bean注解扮演着与<bean/>元素相同的角色。

一个简单@Configuration 类如下:

// 这代表一个配置类,相当于之前的ApplicationContext.xml
@Configuration
public class AppConfig {

    // 这里相当于注册一个bean,等同于之前写的一个bean标签
    // transferService等同于id属性
    // 返回值相当于bean标签的class
    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}

相当于:

<beans>
    <bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>

实例化Spring容器

我们知道,当时我们写ApplicationContext.xml时,是这样实例化的

new ClassPathXmlApplicationContext("ApplicationContext.xml");

而现在我们不再那么实例化,而是:

new AnnotationConfigApplicationContext(xxx.class);

现在取得是class文件(是不是类似MyBatis的用法),而并非之前的xml文件。现在这种通用ApplicationContext实现不仅能够接受@Configuration类作为输入,还能够接受普通@Component类和用 JSR-330 元数据注释的类。

@Configuration类作为输入提供时,@Configuration类本身被注册为 bean 定义,并且@Bean类中所有声明的方法也被注册为 bean 定义。

@Component和 JSR-330 类被提供时,它们被注册为 bean 定义,并且假定 DI 元数据如@Autowired@Inject在必要时在这些类中使用。

启用组件扫描

在利用注解配置容器时需要配置扫描,用到的是:

<beans>
    <context:component-scan base-package="com.acme"/>
</beans>

这样当扫描com.acme包时,就能查找带@Component注解的类,并将这些类注册为容器内的Spring bean定义。

AnnotationConfigApplicationContext允许通过scan(String) 实现相同的组件扫描功能。

public static void main(String[] args) {
    AnnotationConfigApplicationContext ctx = new
    AnnotationConfigApplicationContext();
    ctx.scan("com.acme");
    ctx.refresh();
    MyService myService = ctx.getBean(MyService.class);
}

⚠️注意:也可以将@ComponentScan("acme"),使用在acme类上(效果一样)。

使用@Bean注解

@Bean的方法级别的注解,是XML的直接模拟。@Bean可以使用在@Configuration或@Component类中。

声明一个Bean

通过@Bean注解可以声明一个bean。可以使用此方法在ApplicationContext指定方法返回值的类型类注册bean的定义(返回值为bean)。

默认情况下,bean名称于方法名相同!

@Configuration
public class AppConfig {
    
    @Bean
    public TransferServiceImpl transferService() {
        return new TransferServiceImpl();
    }
}

相当于:

<beans>
    <bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>

上面代码实现的是:

//bean命名为transferService,绑定到类型的对象实例TransferServiceImpl
transferService -> com.acme.TransferServiceImpl

指定Bean的范围

通过@Scope注解能够指定bean的范围。默认为单例模式(singleton)。

与实体类定义范围类似。

@Configuration
public class MyConfiguration {

    @Bean
    @Scope("prototype")
    public Encryptor encryptor() {
        // ...
    }
}

Bean自定义命名

默认情况下,@Bean使用方法名作为bean的名称,但是也可以通过定义其他名称来覆盖默认值。

@Configuration
public class AppConfig {

    @Bean("myThing")
    public Thing thing() {
        return new Thing();
    }
}

同样,使用此方法可以定义多个别名:

@Configuration
public class AppConfig {

    @Bean({"dataSource", "subsystemA-dataSource", "subsystemB-dataSource"})
    public DataSource dataSource() {
        // instantiate, configure and return DataSource bean...
    }
}

Bean描述

Spring可以给bean提供了@Description注解,我们可以定义详细的文本描述:

@Configuration
public class AppConfig {

    @Bean
    @Description("Provides a basic example of a bean")
    public Thing thing() {
        return new Thing();
    }
}

Bean的依赖

使用@Bean方法可以具有描述构建bean所需要的任意数量的依赖关系,当@Bean依赖对方时,表达依赖的方式也很简单,只需要有一个bean方法调用另一个:

@Configuration
public class AppConfig {
   @Bean
   public Foo foo() {
      return new Foo(bar());
   }
   @Bean
   public Bar bar() {
      return new Bar();
   }
}

@Import注解

当我们定义了多个配置类时,由于实例化上下文时需要指定到对应的配置类,这就加大了代码量。

通过@Import注解可以将多个配置类合并为一个。

@Configuration
public class ConfigA {
   @Bean
   public A a() {
      return new A(); 
   }
}
@Configuration
@Import(ConfigA.class) // 导入上面定义好的配置类ConfigA
public class ConfigB {
   @Bean
   public B b() {
      return new B(); 
   }
}
public static void main(String[] args) {
   ApplicationContext ctx = 
   new AnnotationConfigApplicationContext(ConfigB.class);
   // 现在,两个bean A和B都将可用……
   A a = ctx.getBean(A.class);
   B b = ctx.getBean(B.class);
}

生命周期回调

@Bean 注解支持指定任意的初始化和销毁的回调方法。如果 bean 实现InitializingBeanDisposableBeanLifecycle,则容器会调用它们各自的方法。

public class BeanOne {

    public void init() {
        // initialization logic
    }
}

public class BeanTwo {

    public void cleanup() {
        // destruction logic
    }
}

@Configuration
public class AppConfig {

    @Bean(initMethod = "init")
    public BeanOne beanOne() {
        return new BeanOne();
    }

    @Bean(destroyMethod = "cleanup")
    public BeanTwo beanTwo() {
        return new BeanTwo();
    }
}

Java容器配置小结

@Configuration:这代表一个配置类,相当于之前的ApplicationContext.xml

@Bean:这里相当于注册一个bean,等同于之前写的一个bean标签

 
 
参考:
Core Technologies
Spring 基于 Java 的配置

 


❤️ END ❤️
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JOEL-T99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值