Spring 学习总结笔记【三、注解开发】

往期文章:

Spring 学习总结笔记【一、快速入门】
Spring 学习总结笔记【二、IoC-控制反转】

一、 注解介绍

Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xm配置文件可以简化配置,提高开发效率。
Spring注解方式减少了配置文件内容,更加便于管理,并且使用注解可以大大提高了开发效率!
注解本身是没有功能的,和xml一样,注解和xml都是一种元数据,元数据即解释数据的数据,也就是所谓的配置。

  • xml用来管理bean;
  • 注解只负责完成属性的注入;

二、Spring原始注解

1. 基于原始注解进行配置开发

Spring原始注解主要是替代<Bean>的配置

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

从 Spring 2.5 开始就可以使用注解来配置依赖注入。而不是采用 XML 来描述一个 bean ,可以使用相关类,属性声明的注解,将 bean 配置移动到组件类本身,这样可以减少大量配置。当然我们需要完成两个前提条件,使用注解开发时,需要在Spring核心配置文件中配置组件扫描,作用是指定哪个包及其其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法
在这里插入图片描述

<?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
	http://www.springframework.org/schema/context/spring-context.xsd">
	wesd
	<context:annotation-config/>
	<context:component-scan base-package="com.tyt"/>
</beans>

2. 属性注入的Bean注解

可使用注解@Component@Scope@Value处理属性的注入。

@Component("bookDao")
@Scope("prototype")
public class BookDaoImpl implements BookDao {
    @Value("tyt")
    private String name;
}

1. @Component注解

相当于配置文件中的以下代码:

<bean id="bookDao" class="com.tyt.dao.impl.BookDaoImpl"></bean>

2. @Scope注解

相当于配置文件中的以下代码:

<bean id="bookDao" class="com.tyt.dao.impl.BookDaoImpl" scope="prototype"></bean>

3. @Value注解

相当于配置文件中的以下代码:

<property name="name" value="tyt"></property>

2. @Component衍生注解

@Component有三个衍生注解,它们的作用同Component时一样的,不同的命名只不过为了区分不同的层,为了更好的进行分层,Spring可以使用其它三个注解,目前使用哪一个功能都一样。

  • @Controller:Controller层,也就是控制层,接口请求的入口
  • @Service:service层,业务逻辑层,具体的业务逻辑实现层
  • @Repository:dao层,持久化层,和数据库交互的层

3. 自动装配的注解

Spring 学习总结笔记【一、快速入门】谈到过Spring是如何通过自动装备将依赖自动进行装配的,具体实现细节是byNamebyType,这里的自动装配注解也是为自动装配服务的。
Spring将依赖自动进行装配,具体实现细节是byName和byType,这里的自动装配注解也是为自动装配服务的。

1. @Autowired 注解

@Autowired是按类型byType自动转配的,不支持id也就是byName匹配:

@Service("bookService")
public class BookServiceImpl implements BookService {

    // 自动装配
    @Autowired
    private BookDao bookDao;
}

相当于配置文件中的以下代码:

<bean id="bookService" class="com.tyt.service.impl.BookServiceImpl" autowire="byType"></bean>

2. @Qualifier注解

@Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配,@Qualifier不能单独使用,必须结合@Autowired一起使用。
在使用@Qualifier之前,仅使用@Autowired,如果有两个类型一样的:

<bean id="bookDao" class="com.tyt.dao.impl.BookDaoImpl"/>
<bean id="bookDao222" class="com.tytdao.impl.BookDaoImpl"/>

那么会报类型发现多个的错误:NoUniqueBeanDefinitionException
配置上@Qualifier 注解后,也可以使用多个相同类型了,每次可以指定一个使用:

@Service("bookService")
public class BookServiceImpl implements BookService {

    // 自动装配
    @Autowired
    @Qualifier(value="bookDao")
    private BookDao bookDao;
}

相当于配置文件中的以下代码:

<bean id="bookService" class="com.tyt.service.impl.BookServiceImpl" autowire="byType">
	<property name="bookDao" ref="bookDao" />
</bean>

3. @Resource 注解

@Resource 相当于 @Qualifier + @Autowired

@Resource

  • 如指定了name属性,则先按该属性进行byName方式进行装配;
  • 如果没有指定name属性 ①如果注解写在字段上,默认取字段名进行装配 ②如果注解写在setter方法上,默认取属性名进行装配
  • 如果以上都不成功,则按byType的方式自动装配
  • 都不成功,则报异常。
@Service("bookService")
public class BookServiceImpl implements BookService {

    @Resource("bookDao")
    private BookDao bookDao;
}

4. 三者区别

  • @Autowired默认按类型装配,默认情况下必须要求依赖对象存在,如果要允许null值,可以设置它的required属性为false。如果想使用名称装配可以结合@Qualifier注解进行使用
  • @Qualifier 接口可以有多个实现类,可以按实现类的类名进行注入
  • @Resource 接口可以有多个实现类,先通过byName方式进行匹配,若匹配失败再通过byType方式注入

4. 生命周期注解

  • @PostConstruct:标注该方法是Bean的初始化方法
  • @PreDestroy:标注该方法是Bean的销毁方法
@Repository("bookDao")
@Scope("prototype")
public class BookDaoImpl implements BookDao {

	@Value("tyt")
	private String name;
	
	// 初始化方法
	@PostConstruct
	public void init(){
		System.out.println("init----");
	}
	
	// 销毁方法
	@PreDestroy
	public void destroy(){
		System.out.println("destroy----");
	}
}

相当于配置文件中的以下代码:

<bean id="bookDao" class="com.tyt.Dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy">
	<property name="name" ref="tyt" />
</bean>

三、Spring新注解

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

  • 非自定义的Bean的配置:<bean>
  • 加载properties文件的配置:<context:property-placeholder>
  • 组件扫描的配置:<context:component-scan>
  • 引入其他文件:<import>

Spring新注解如下:

注解说明
@Configuration用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解
@ComponentScan用于指定Spring在初始化容器时要扫描的包。作用同在Spring核心配置文件中的<context:component-scan base-package="com.tyt"/>相同
@Import用于导入其他配置类
@Bean使用在方法上,标注将该方法的返回值存储到Spring容器中
@PropertySource用于加载.properties文件中的配置信息

新注解的出现又为Spring的开发方式(基于xml配置方式,注解开发)增加了一项基于Java类进行配置开发,不需要任何xml配置文件,事实上,Config类代替了xml配置文件。

1. @Configuration注解

标志当前类是Spring的核心配置类

2. @ComponentScan注解

指定Spring在初始化容器时要扫描的包

3. @Import注解

用于导入其他配置类

4. @Bean注解

使用在方法上,标注将该方法的返回值存储到Spring容器中

5. @PropertySource注解

用于加载.properties文件中的配置信息

6. JavaConfig类编写

① 首先定义一个 Jdbc.properties

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

② 定义一个JdbcConfig类

@PropertySource("jdbc.properties")
public class JdbcConfig {

    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.name}")
    private String name;
    @Value("${jdbc.password}")
    private String password;

    // 定义一个方法获得要管理的对象
    // 添加 Bean, 表示当前方法返回值为一个 Bean
    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(name);
        ds.setPassword(password);
        return ds;
    }
}

相当于配置文件(命名为JdbcConfig.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
            http://www.springframework.org/schema/context/spring-context.xsd">
            
    <!-- 1、开启context命名空间,需要添加上述和context有关的信息 -->
    <!-- 2、使用context加载配置文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- 3、使用${}动态获取值 -->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

③ 定义SpringConfig类


@Configuration
@ComponentScan({"com.tyt.dao", "com.tyt.service"})
@Import({JdbcConfig.class})
public class SpringConfig {
    /*
    *  第三方 bean 管理, 如 数据库连接池,也可将其写入其他配置类,使用@Import加载即可
    * */
}

相当于配置文件(命名为SpringConfig.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
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>
    <context:component-scan base-package="com.tyt.dao"/>
    <context:component-scan base-package="com.tyt.service"/>
    
	<import resource="JdbcConfig.xml"/>
</beans>

④ 使用Spring的API获取Bean的实例

public static void main(String[] args) {
	ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfig.class);
	BookDao bookDao = app.getBean("bookDao", BookDao.class);
	bookDao.save();
	
	BookService bookService = app.getBean("bookService", BookService.class);
	bookService.save();
	
	DataSource dataSource = app.getBean(DataSource.class);
	System.out.println(dataSource);
}

总结
到这篇为止,终于全面了解了基于元数据的IOC注入模式:XML配置、注解模式、Java配置类,这几种都可以混合使用,在合适的场景使用合适的元数据注入模式,XML比较清晰,注解模式比较快捷,Java配置类模式完全不依赖配置文件,只能说各有特色。

下期文章:

Spring 学习总结笔记【四、整合Junit】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值