spring注解开发

在这里插入图片描述

前言

Spring中用于管理bean的注解分为四大类:

  • 用于创建对象
  • 用于给对象中的属性注入值
  • 用于改变作用范围
  • 用于定义生命周期

使用注解需要导入 spring-aop-5.2.6.RELEASE.jar
相关文件链接:spring5.2.6jar包等


相关面试题

@Component、@Controller、@Service、@Repository有何区别?
@Autowired和@Resource的区别?
什么是基于注解的容器配置?


前期准备

编写业务层接口 UserService、业务层实现类 UserServiceImpl

/**
 * @Author: Ron
 * @Create: 2020 9:37
 */
public interface UserService {
    public void save();
}
/**
 * @Author: Ron
 * @Create: 2020 9:38
 */
public class UserServiceImpl implements UserService {

    private String msg;

    @Override
    public void save() {
        System.out.println("业务层保存成功。。。。" + msg);
    }
}

编写持久层接口 UserDao、持久层实现类 UserDaoImpl

/**
 * @Author: Ron
 * @Create: 2020 17:31
 */
public interface UserDao {
   void insert();
}
/**
 * @Author: Ron
 * @Create: 2020 17:32
 */
public class UserDaoImpl implements UserDao {
    @Override
    public void insert() {
        System.out.println("持久层初始化。。。UserDaoImpl");
    }
}

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">

    <!-- 开启注解扫描,base-package:指定扫描的包,会扫描该包及其子子孙孙包下的所有类 -->
    <context:component-scan base-package="com.test.spring5"></context:component-scan>

</beans>

1.管理bean的四类注解

1.1.用于创建bean对象

用于创建对象的有四个:@Component@Controller@Service@Repository

1.1.1.@Component

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

    @Test
    public void test004() {
        // 1加载spring配置文件
        ApplicationContext context =
                new ClassPathXmlApplicationContext("service.xml");
        // 2获取bean对象
        UserService userService = context.getBean("userService", UserServiceImpl.class);
        userService.save();
    }

在这里插入图片描述
解决方案:
在这里插入图片描述
测试成功
在这里插入图片描述

1.1.2.@Controller @Service @Repository

@Controller:一般用于表现层实现类的注解。
@Service:一般用于业务层实现类的注解。
@Repository:一般用于持久层实现类的注解。
在这里插入图片描述

面试题:@Component、@Controller、@Service、@Repository有何区别?

@Component、@Controller、@Service、@Repository有何区别:
@Controller@Service@Repository三个注解都是针对@Component的衍生注解,他们的作用及属性都是一模一样的。
他们只不过是提供了更加明确的语义化。让标注类本身的用途更加清晰

1.2.用于给对象中的属性注入值

用于注入数据的注解有:@Value@Autowired@Qualifier@Resource
相当于 property name="" value=""

1.2.1.@Value

@Value(value=“xxxx”)
作用: 注入 基本数据类型String类型 数据的
value: 用于指定值
在这里插入图片描述
UserServiceImpl没有set方法
在这里插入图片描述

1.2.2.@Autowired

自动 按照类型注入。当使用注解注入属性时,set方法可以省略。它 只能注入其他bean类型 。当有多个类型匹配时,使用要注入的对象变量名称作为bean的id,在spring容器查找,找到了也可以注入成功。找不到就报错。
在这里插入图片描述
测试
在这里插入图片描述
新增 UserDaoImpl2 实现 UserDao 接口

/**
 * @Author: Ron
 * @Create: 2020 17:32
 */
@Repository
public class UserDaoImpl2 implements UserDao {
    @Override
    public void insert() {
        System.out.println("持久层初始化。。。UserDaoImpl2");
    }
}

在这里插入图片描述
怎么解决?两种方案:

  1. 把其中一个实现类的bean Id设置为userDao,或者把属性名改成userDaoImpl或者userDaoImpl2
    在这里插入图片描述

  2. 使用@Qualifier注解

1.2.3.@Qualifier

在自动按照类型注入的基础之上,再按照Bean的id注入。它在给字段注入时不能独立使用,必须和@Autowire一起使用;但是给方法参数注入时,可以独立使用。
在这里插入图片描述
测试成功

1.2.4.@Resource

Spring提供了对JSR-250中@Resource注解的支持。
@Resource的装配顺序:
1、@Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配
2、指定了name或者type则根据指定的类型去匹配bean
3、指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错
在这里插入图片描述
也可以指定使用byType
在这里插入图片描述

面试题:@Autowired和@Resource的区别?

@Autowired和@Resource两个注解的区别:
@Autowired 默认按照byType方式进行bean匹配,@Resource 默认按照byName方式进行bean匹配
@Autowired 是Spring的注解,@Resource 是J2EE的注解,这个看一下导入注解的时候这两个注解的包名就一清二楚了
Spring属于第三方的,J2EE是Java自己的东西,因此,建议使用@Resource注解,以减少代码和Spring之间的耦合

1.3.用于改变作用Bean作用域范围

ScopeDescription
singleton(默认值)每个 Spring IoC 容器将单个 bean 定义范围限制到单个对象实例。
prototype将单个 bean 定义的作用域限定为任意数量的对象实例。
request将单个 bean 定义的范围限定为单个 HTTP 请求的生命周期;也就是说,每个 HTTP 请求都有一个自己的 bean 实例,它是在单个 bean 定义的后面创建的。仅在可感知网络的 Spring ApplicationContext 中有效。
session将单个 bean 定义的范围限定为 HTTP Session 的生命周期。仅在可感知网络的 Spring ApplicationContext 上下文中有效。
application将单个 bean 定义的范围限定为 ServletContext 的生命周期。仅在可感知网络的 Spring ApplicationContext 上下文中有效。
websocket将单个 bean 定义的范围限定为 WebSocket 的生命周期。仅在可感知网络的 Spring ApplicationContext 上下文中有效。

在这里插入图片描述

1.4.用于定义生命周期

相当于:
@PostConstruct 加在方法上,指定bean对象创建好之后,调用该方法初始化对象,类似于xml的init-method方法。
@PreDestory 加在方法上,指定bean销毁之前,调用该方法,类似于xml的destory-method方法。
在这里插入图片描述
修改 UserServiceImpl 代码和 测试方法

/**
 * @Author: Ron
 * @Create: 2020 9:38
 */
@Component
public class UserServiceImpl implements UserService {

    @Value("哈哈哈,干饭人")
    private String msg;

    //@Autowired(required=false) //注入对象类型,按照类型注入;如果有多个,则根据属性名注入
    //@Qualifier("userDaoImpl2") // 结合@Autowired注解使用,当有多个Bean的类型符合要求时,指定注入bean的id
    //@Resource(name="userDaoImpl") // 按照id注入对象类型,name指定bean的id
    @Resource(type=UserDaoImpl.class)
    private UserDao userDao;

    @Override
    public void save() {
        this.userDao.insert();
        System.out.println("业务层保存成功。。。。" + msg);
    }
    @PostConstruct
    public void init(){
        System.out.println("执行了init方法。。。。");
    }

    @PreDestroy
    public void destroy(){
        System.out.println("执行了Destroy方法。。。。");
    }

}

注意:要使 destroy() 能正常执行,UserServiceImpl必须是 单例 的,并且 容器必须关闭

测试方法(ApplicationContext没有提供容器关闭方法,使用AbstractApplicationContext创建IoC容器)

    @Test
    public void test004() {
        // 1加载spring配置文件
        // ApplicationContext更换为AbstractApplicationContext
        // AbstractApplicationContext有close()f方法,可手动关闭容器
        AbstractApplicationContext context =
                new ClassPathXmlApplicationContext("service.xml");
        // 2获取bean对象
        UserService userService = context.getBean("userServiceImpl", UserServiceImpl.class);
        userService.save();
        context.close();
    }

在这里插入图片描述


2.XML和注解的比较

注解的优势:
配置简单,维护方便。(我们找到了类,就相当于找到了配置)
XML的优势:
修改时,不用改源码。不涉及重新编译和部署。
Xml和注解的比较:
在这里插入图片描述


3.例:注解和XML

将注解的实例改为使用XML配置文件
第一步,在 UserServiceImpl 中新增 set() 方法
在这里插入图片描述
第二步,在xml中关闭注解扫描,创建相关bean对象,并进行数据注入

    <!-- 开启注解扫描,base-package:指定扫描的包,会扫描该包及其子子孙孙包下的所有类 -->
<!--    <context:component-scan base-package="com.test.spring5"></context:component-scan>-->

    <!--创建bean对象 init-method相关于@PostConstruct destroy-method相当于@PreDestroy-->
    <bean id="userServiceImpl" class="com.test.spring5.service.impl.UserServiceImpl" init-method="init" destroy-method="destroy">
        <!--属性注入-->
        <property name="msg" value="嘻嘻嘻,打工人"></property>
        <!--ref 引用注入-->
        <property name="userDao" ref="userDaoImpl"></property>

    </bean>
    <bean id="userDaoImpl" class="com.test.spring5.dao.UserDaoImpl"></bean>
    <bean id="userDaoImpl2" class="com.test.spring5.dao.UserDaoImpl2"></bean>

第三步,测试
在这里插入图片描述

4.完全注解开发

(1) 创建配置类 SpringConfig,替代 xml 配置文件

/**
 * @Author: Ron
 * @Create: 2020 8:47
 */
@Configuration
@ComponentScan(basePackages = {"com.test.spring5"})
public class SpringConfig {
}

(2) 编写测试方法

    @Test
    public void testService() {
        // 1加载配置类
        ApplicationContext context
                = new AnnotationConfigApplicationContext(SpringConfig.class);
        // 2获取bean对象
        UserService userService = context.getBean("userServiceImpl", UserServiceImpl.class);
        userService.save();
    }

测试结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值