Spring之注解

原始注解

Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。注解主要替代Bean标签配置

注解 说明 序号
@Component 使用在类上用于实例化Bean 1
@Controller 使用在web层类上用于实例化Bean 2
@Service 使用在service层类上用于实例化Bean 3
@Repository 使用在dao层类上用于实例化Bean 4
@Autowired 使用在字段上用于根据类型依赖注入 5
@Qualifier 结合@Autowired一起使用用于根据名称进行依赖注入 6
@Resource 相当于@Autowired+@Qualifier,按照名称进行注入 7
@Value 注入普通属性 8
@Scope 标注Bean的作用范围 9
@PostConstruct 使用在方法上标注该方法是Bean的初始化方法 10
@PreDestroy 使用在方法上标注该方法是Bean的销毁方法 11

使用注解进行开发时,需要在applicationContext.xml中配置组件扫面,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法。

<!--    配置组件扫描-->
    <context:component-scan base-package="com.itheima"/>

在使用context之前,需要在文件顶部加入声明。基本做法是将xmlns后的值copy一份,将最后面的beans改为context,然后在xmlns后加入context,之后复制xsi:schemaLocation中的值在值后面粘贴,将beans改为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
">

实例

package com.itheima.dao.impl;

import com.itheima.dao.UserDao;
import org.springframework.stereotype.Repository;

// <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("save running......");
    }
}
package com.itheima.service.impl;

import com.itheima.dao.UserDao;
import com.itheima.service.UserService;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

// <bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
@Service("userService")
//@Scope("prototype")
//@Scope("singleton")
public class UserServiceImpl implements UserService, InitializingBean, DisposableBean {

    @Value("${jdbc.driver}") // 从Spring容器中找到对应的key赋值给driver
    private String driver;


    // <property name="userDao" ref="userDao"/>
    @Autowired // 按照数据类型从Spring容器中匹配,在Spring中找到UserDao类型的Bean注入
    @Qualifier("userDao") // 按照id从Spring容器中匹配,在Spring中找到对应id类型的Bean注入,但是Qualifier要结合Autowired一起使用
    // @Resource(name="userDao") // 相当于Autowired与Qualifier结合
    private UserDao userDao;

    @Override
    public void save() {
        System.out.println(driver);
        userDao.save();
    }

//    @PostConstruct
//    public void init() {
//        System.out.println("init......");
//    }
//
//    @PreDestroy
//    public void destory() {
//        System.out.println("init......");
//    }

    @Override
    public void destroy() throws Exception {
        System.out.println("destroy....");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("init....");
    }
}

在新版本的Java中,原始注解的@PostConstruct@PreDestroyafterPropertiesSet()destroy()替代,只需要在类开头实现InitializingBean, DisposableBean这两个接口。

新注解

使用上面的原始注解不能全部替代xml配置文件,还需要使用注解替代的配置如下:

  • 非自定义的Bean的配置
  • 加载properties文件的配置
  • 组件扫描的配置
  • 引入其他文件
注解 说明 序号
@Configuration 用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解 1
@ComponentScan 用于指定Spring在初始化容器时要扫描的包 2
@Bean 使用在方法上,标注将该方法的返回值存储的Spring容器中 3
@PropertySource 用于加载properties文件中的配置 4
@Import 用于导入其他配置类 5

实例

package com.itheima.config;

import org.springframework.context.annotation.*;

@Configuration // 标志该类是Spring的核心配置类

//<!--    配置组件扫描-->
//<context:component-scan base-package="com.itheima"/>
@ComponentScan("com.itheima")

//<import resource=""/>
@Import({DataSourceConfiguration.class})

public class SpringConfiguration {

}

创建SpringConfiguration类替代Spring配置文件(applicationContext.xml)

package com.itheima.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

//<!--    加载外部的properties文件-->
//<context:property-placeholder location="classpath:jdbc.properties"/>
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean("dataSource") // Spring会将当前方法的返回值以指定名称存储到Spring容器中
    public DataSource getDataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

创建额外的配置类,使代码可读性更高。

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root

properties文件会被DataSourceConfiguration读取,同时使用@Value获取文件中的值并赋值给字符串,在getDataSource()方法中设置对应字符串来配置数据源,最后返回DataSource类型的数据。

// 假设的一个表示层
public class UserController {
    public static void main(String[] args) {
        ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        UserService bean = app.getBean(UserService.class);
        bean.save();
    }
}

表示层读取配置文件就需要变为AnnotationConfigApplicationContext,其余不变。

posted @ 2021-12-14 11:05  喵酱的花椒  阅读(47)  评论(0)    收藏  举报