Spring(三)注解配置

要使用注解方式配置bean,还需要导入spring-aop这个jar包:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.3.3</version>
</dependency>

依旧需要创建一个applicationContext.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.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<!--    开启注解,指定要扫描的包(Spring将会扫描该包下以及其子包下的所有类上是否有注解)-->
    <context:component-scan base-package="com.dh.pojos"/>
</beans>

然后只需要在要放入容器中的类上加上注解:共有四个

@Component,@Controller,@Service,@Repository

四个的作用都是一样的,只是为了方便程序员区分类,@Controller放在servlet类中,@Service放在service类中,@Repository放在dao类中。

在类的最上方加上注解:

package com.dh.pojos;

import org.springframework.stereotype.Component;

@Component
//在注解时也可以指定一个名字
//@Component("person")
public class Person {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试:测试同xml配置

import com.dh.pojos.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest01 {

    @Test
    public void test01(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //如果没有指定名字可以使用类名小写开头的类名
        //指定了名字可以使用名字
        Person person = (Person) applicationContext.getBean("person");
        System.out.println(person);
        //还可以使用类名.class
        Person person1 = applicationContext.getBean(Person.class);
        System.out.println(person1);
    }
}

那么如何进行依赖注入呢?

对属性进行依赖注入也有相应的注解:

@Value:用于对普通属性赋值;

@Autowired:用于对复杂属性赋值;

@Qualifier:弥补@Autowired的缺陷,可以指定JavaBean的id;

@Resource:java扩展的注解。

在Person类中添加其它复杂的属性:

private String name;
private int age;
private Dog dog;
private String driver;

然后为其注入值:

//普通值
@Value("Tom")
private String name;
//SpEL表达式
@Value("#{18+2}")
private int age;
//其它bean
@Autowired
private Dog dog;
//properties文件中的值
@Value("${jdbc.driver}")
private String driver;

注意,需要在applicationContext中加载配置文件:

<context:property-placeholder location="classpath:jdbc.properties"/>

结果:

Person{name='Tom', age=20, dog=Dog{type='null', color='null'}, driver=com.mysql.cj.jdbc.Driver}

@Autowired是利用类型来注入的,当有多个的时候就会报错:

比如:

一个接口:

package com.dh.service;

public interface UserService {
}

两个实现类,并使用注解放入容器:

package com.dh.service;

import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl1 implements UserService {
}
package com.dh.service;

import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl2 implements UserService {
}

此时有一个User类:

package com.dh.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class User {
    @Autowired
    private UserService userService;

    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Override
    public String toString() {
        return "User{" +
                "userService=" + userService +
                '}';
    }
}

测试:

User user = applicationContext.getBean(User.class);
System.out.println(user);

结果会发生异常,截取主要的详细:

No qualifying bean of type 'com.dh.service.UserService' available: expected single matching bean but found 2: userServiceImpl1,userServiceImpl2

因为使用@Autowired找UserService找到了两个,所以Spring不知道是哪个。

此时就需要@Qualifier出场了,指定所需要的JavaBean的id:

@Autowired
@Qualifier("userServiceImpl1")
private UserService userService;

或者可以直接使用@Resource注解

要使用此注解,需要导入jar包:

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>
//同时指定name和type
@Resource(name = "userServiceImpl1",type = UserServiceImpl1.class)
private UserService userService;

注解设置作用域

在类中使用@Scope注解就可以配置类的作用域了。

@Component
@Scope("prototype")
public class User {
}

注解和xml联合使用

虽然注解很强大,但是对于一些别人写好的类,我们就没有办法去加注解了,此时就只能使用xml配置了。

而Spring是支持注解和xml联合使用的:

如:

使用xml配置bean,使用注解实现依赖注入

<bean id="person2" class="com.dh.pojos.Person"/>
<bean id="dog2" class="com.dh.pojos.Dog"/>
<!--    开启扫描注解-->
<context:annotation-config/>
public class Person {
    @Autowired
    private Dog dog;
}

多文件配置

当配置文件中的内容太多时,就可以分开在几个不同的文件中书写,那么如何同时加载呢?

方法一:

new ClassPathXmlApplicationContext("file1","file2",...);

方法二:

在一个配置文件中引入其它配置文件:

<import resource="file_name"/>

然后只需要加载主文件即可。

posted @ 2021-04-01 10:37  deng-hui  阅读(139)  评论(0编辑  收藏  举报