【Spring学习04】Spring基于IOC的注解配置和Spring新注解

  学习基于注解的 IoC 配置,大家脑海里首先得有一个认知,即注解配置和 xml 配置要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。 关于实际的开发中到底使用xml还是注解,每家公司有着不同的使用习惯。所以这两种配置方式我们都需要掌握。

一、Spring基于IOC的注解配置

注意:在基于注解的配置中,我们还要多拷贝一个 aop 的 jar 包。

  1. 在上一篇博客中已经介绍了导入Maven依赖包,在这里aop的包已经存在了。
    在这里插入图片描述
  2. 使用@Component 注解配置管理的资源 ,新建一个Maven工程或模块,新建com.xnch.dao包,创建IAccountDao接口及其实现方法,service层及实现方法
  • IAccountDao.java
/**
 * 账户的持久层接口
 */
public interface IAccountDao {

    /**
     * 模拟保存账户
     */
    void saveAccount();
}
  • IAccountDaoImpl.java
/**
 * 账户的持久层实现类
 */
@Component("accountDao")
public class AccountDaoImpl implements IAccountDao {

    public  void saveAccount(){
        System.out.println("保存了账户");
    }
}
  • AccountServiceImpl.java
@Component(value = "accountService")
public class AccountServiceImpl implements IAccountService {

	@Autowired
    private IAccountDao accountDao;

    public AccountServiceImpl(){
        System.out.println("对象创建了");
    }

    public void  saveAccount(){
        accountDao.saveAccount();
    }

}
  1. 全局配置文件beans.xml,在这里和之前的xml有所不同,因为要配置支持注解支持,所以添加了xmlns:context依赖支持。
<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">
<!--告知spring创建容器时要扫描的包,配置所需要的标签不是在beans的约束中,而是一个名称为context名称空间和约束-->
    <context:component-scan base-package="com.xnch"/>
</beans>

二、常用注解

2.1、用于创建对象的

相当于配置文件中的:

<bean id="" class=""> 

2.1.1、 @Component

  作用:
    把资源让 spring 来管理。相当于在 xml 中配置一个 bean。
  属性:
    value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名(首字母小写)。

2.1.2、@Controller @Service @Repository

  他们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。 他们只不过是提供了更加明确的语义化。

  • @Controller:一般用于表现层的注解。
  • @Service:一般用于业务层的注解。
  • @Repository:一般用于持久层的注解。

  以上三个注解他们的作用和属性与Component是一模一样。如果注解中有且只有一个属性要赋值时,且名称是 value,value属性在赋值时可以不写。 他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰。

2.2、用于注入数据的

相当于配置文件中的:

<property name="" ref="">      
<property name="" value=""> 

2.2.1、@Autowired

  作用:
    自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他 bean 类型。当有多个类型匹配时,使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到就报错。
  出现位置:
    可以是变量上,也可以是方法上
在使用注解注入时,set方法就不是必须的了。

  • 演示有多个类型匹配时报错的情况

在这里主要是写了两个IAccountDao的实现类,代码如下:
在这里插入图片描述

/**
 * 账户的持久层实现类1
 */
@Repository
public class AccountDaoImpl implements IAccountDao {

    public  void saveAccount(){
        System.out.println("保存了账户11111111111111111111111");
    }
}


/**
 * 账户的持久层实现类2
 */
@Repository
public class AccountDaoImpl2 implements IAccountDao{

    public  void saveAccount(){

        System.out.println("保存了账户222222222222222222222222");
    }
}

测试类:

    /**
     * 测试方法
     * @param args
     */
    public static void main(String[] args) {
        //1.获取核心容器对象
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        //2.根据id获取Bean对象
        IAccountService as  = (IAccountService)ac.getBean("accountService");
        as.saveAccount();
    }

service层的代码不变,点击运行测试类,就会出现如下错误,类型的限定bean可用,需要单个匹配bean,但找到2个bean,就报错了。

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘com.xnch.dao.IAccountDao’ available: expected single matching bean but found 2: accountDaoImpl,accountDaoImpl2

解决方案: 在每一个AccountDao的实现类上的注解@Repository加上属性值,比如@Repository("accountDao1") @Repository("accountDao2")同时还需修改service层AccountServiceImpl类的AccountDao的属性。这显然过于麻烦,下面介绍更好用的方法。
在这里插入图片描述

2.2.2、@Qualifier

  作用:
    在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和 @Autowire 一起使用,否则报空指针异常;但是给方法参数注入时,可以独立使用。
  属性:
    value:指定 bean 的 id。
  用法:
    参考上面的问题,也可将accountDao属性上面加上这两个注解,也可以解决多个类型报错的问题。
在这里插入图片描述

2.2.3、@Resource

  作用:
    直接按照bean的id注入。它可以独立使用
  属性:
     name:用于指定bean的id。

  以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。
  另外,集合类型的注入只能通过XML来实现。

    参考上面@Autowired的问题,也可将accountDao属性上面加上@Resource 注解,也可以解决多个类型报错的问题。
在这里插入图片描述

2.2.4、@Value

  作用:
    注入基本数据类型和 String 类型数据的
  属性:
    value:用于指定值 它可以使用spring中SpEL(也就是spring的el表达式) SpEL的写法:${表达式}

2.3、用于改变作用范围的

相当于xml配置中的:

<bean id="" class="" scope=""> 

2.3.1、@Scope

  作用:
    指定 bean 的作用范围。
  属性:
    value:指定范围的值。 取值:singleton prototype request session globalsession

2.4、和生命周期相关的

相当于xml配置中的:

<bean id="" class="" init-method="" destroy-method="" /> 

2.4.1、@PostConstruct

作用: 用于指定初始化方法。

2.4.4、@PreDestroy

作用: 用于指定销毁方法。

三、Spring新注解

  写到此处,基于注解的 IoC 配置已经完成,但是我们可能都发现了一个问题:我们依然离不开 spring 的 xml 配置文件,那么能不能不写这个 bean.xml,所有配置都用注解来实现呢? 那么Spring的新注解就能解决这个问题。

  我们发现,之所以我们现在离不开 xml 配置文件,是因为我们有一句很关键的配置: 告知spring框架在,读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中。

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

如果它要也能用注解配置,那么我们就离脱离 xml 文件就又进了一步。 看到这里,请先看另一篇博客,以便对下面介绍新注解的更容易理解。https://blog.csdn.net/weixin_43800761/article/details/103323356

3.1.1、@Configuration

  作用:
    用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用 AnnotationApplicationContext(有@Configuration 注解的类.class)。
  属性:
    value:用于指定配置类的字节码
在这里插入图片描述
我们已经把配置文件用类来代替了,但是如何配置创建容器时要扫描的包呢? 请看下一个注解。

3.1.2、 @ComponentScan

  作用:
    用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的: <context:component-scan base-package="com.xnch"/>是一样的。
  属性:
    basePackages:用于指定要扫描的包。和该注解中的 value 属性作用一样。
在这里插入图片描述
在这里我们已经配置好了要扫描的包,但是数据源和 JdbcTemplate 对象如何从配置文件中移除呢? 请看下一个注解。

3.1.3、 @Bean

  作用:
    该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。
  属性:
    name:给当前@Bean 注解方法创建的对象指定一个名称(即 bean 的 id)。 不写时,默认值为当前方法的名称。
在这里插入图片描述
当使用注解配置时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象,查找方式与Autowired注解的作用是一样的。

3.1.3、@PropertySource

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

3.1.4、@Import

  作用:
    用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解。当然,写上也没问 题。
  属性:
    value[]:用于指定其他配置类的字节码。
使用Import的注解后,有Import注解的类就是父配置类,而导入的就是子配置类
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43800761/article/details/103318954