Spring 6【Lombok、基于注解方式的IoC】(六)-全面详解(学习总结---从入门到深化)

 

目录

十一、Lombok

十二、基于注解方式的IoC


 

十一、Lombok

在上面的课程讲解过程中,每次修改类的属性,都需要重新生成Getter/Setter方法及toString()方法。我 们可以借助Lombok来简化代码。

1 环境准备

下载Lombok插件

IDEA 2022.3.2 默认集成Lombok插件,不需要单独下载。而且Lombok插件是不允许被卸载的。

Spring 6【Lombok、基于注解方式的IoC】(六)-全面详解(学习总结---从入门到深化)_第1张图片

启用注解处理 

不启用注解处理,也能正常出结果。只是在第一次启动后,会在IDEA右下角提示,请启用注解处理。

Spring 6【Lombok、基于注解方式的IoC】(六)-全面详解(学习总结---从入门到深化)_第2张图片

IDEA菜单 File -> Settings

Spring 6【Lombok、基于注解方式的IoC】(六)-全面详解(学习总结---从入门到深化)_第3张图片 

2. @Data 

Lombok支持的注解比较多,可以从Lombok插件看到所有支持的注解。

Spring 6【Lombok、基于注解方式的IoC】(六)-全面详解(学习总结---从入门到深化)_第4张图片

我们挑选出一些常用的注解,先来看看@Data注解

在类上添加@Data注解 

@Data
public class Person {
    private String name;
    private int age;
}

测试生成的方法

可以使用属性的getter/setter方法。并且进入equals和hashCode()和toString()时是进入到Person类。 而去掉@Data注解时是进入到Object类中,说明@Data也生成equals()和hashCode()和toString()方法。

@Test
void testLombok(){
Person p1 = new Person();
    p1.setName("smallming");
    p1.setAge(18);
    p1.getAge();
    p1.getName();
    p1.equals("");
    p1.hashCode();
    p1.toString();
}

 3. 构造方法处理

默认情况下使用无参构造方法。但是Lombok支持3个对构造方法处理的注解。这三个注解只要使用任意 一个,将不会在有默认的无参构造方法

3.1、@NoArgsConstructor :生成无参数构造方法

3.2、@AllArgsConstructor:生成全参构造方法

3.3、@RequiredArgsConstructor:生成一个包含所有final和 @NonNull属性的构造方法。

4. Getter和Setter处理 

@Getter和@Setter是类和属性注解。可以用在类上表示给所有属性都生成。如果用在某个属性上,表示 只给这个属性生成。

4.1、@Getter 给属性生成getter方法

4.2、@Setter 给属性生成setter方法

5. @ToString

给类生成包含所有属性的toString()方法,除非属性上包含@ToString.Exclude

6. 日志注解 

Lombok支持市面上绝大多数日志。只需要在项目中引入对应日志的依赖。然后就可以在类中直接使用 log对象。

不同的日志类型区别也就是log对象的类型不同:

@Log 原生JDK日志。类型:java.util.logging.Logger

@Log4j apache的日志。类型:org.apache.log4j.Logger

@Log4j2 apache的日志。类型:org.apache.logging.log4j.Logger

@Slf4j 类型:org.slf4j.Logger 

@XSlf4j 类型:org.slf4j.ext.XLogger

@CommonsLog apache的日志。类型:org.apache.commons.logging.Log @JBossLog jboss的日志。类型:org.jboss.logging.Logger

@Flogger 谷歌的日志。类型:com.google.common.flogger.FluentLogger

@CustomLog 自定义日志。类型:自定义的日志类型。

使用时需要导入对应日志依赖。以log4j2举例。在项目中引入


     org.apache.logging.log4j
     log4j-core
     2.20.0

在类中使用log对象(无论哪种日志类型),不再需要实例化。

@Data
@Log4j2
public class Person {
     private String name;
     private int age;
     public void test(){
    // 直接使用log对象,不需要实例化
     log.info("日志信息");
   }
}

十二、基于注解方式的IoC

1.为什么要学习注解方式的IoC

无论什么技术,什么框架。只要是同一个技术即提供了XML配置方式,又提供了注解方式。注解方式都是为了简化XML配置,让代码编写变得更加简单。

Spring 6【Lombok、基于注解方式的IoC】(六)-全面详解(学习总结---从入门到深化)_第5张图片

2.Spring Framework如何开启注解支持 

注解不是写上就生效的。我们需要告诉Spring Framework哪里有注解。这样Spring框架就会去这个包及子包去寻找注解。然后(通过反射)解析注解。

在Spring框架配置文件添加context命名空间及xsd文件路径。并使用标签配置需要Spring框架扫描哪个包及所有子包的注解。





         



3.让IoC容器实例化类对象的注解

类中注解想要生效,前提是当前类的Bean被IoC容器管理。所以我们先来学习下如何让IoC容器实例化类。

@Component注解

我们先来回顾下使用XML方式对类进行实例化的方式。

配置时只有两处:

       1、Bean在IoC容器中的名称

       2、类的全限定路径

而使用注解时,只需要把注解放在类上,就知道了类的权限定路径。也就是说使用注解只需要配置下 Bean在IoC容器中的名称就可以了。

@Component注解就是负责告诉IoC容器,需要对当前类实例化的。

@Component注解里面只有value属性。value属性用于配置Bean的名称,可省略。

Spring 6【Lombok、基于注解方式的IoC】(六)-全面详解(学习总结---从入门到深化)_第6张图片

具体代码示例:

@Component(value="bean的名称")
//@Component("bean的名称") value可省略
//@Component 不写bean的名称时,bean的名称为类名首字母变小写,其他字母不变。

public class Person {


}

 @Component注解的子注解

@Component注解一共有四个子注解。这四个子注解功能和@Component注解完全相同。唯一的区别 是语义上有区别。语义区别是指:为了方便程序员阅读代码,提升代码规范,不同类型的类上应该用不 同的注解。

    @Repository :数据访问层,类上注解。常用在XXXDaoImpl类上。

    @Service:业务层,类上注解。常用在XXXServiceImpl类上。

    @Controller:控制层,类上注解。常用在XXXController类上。Spring MVC时控制器上注解。

    @Configuration:配置类,类上注解。当使用Java类方式对Spring框架进行配置时使用。

    @Component:不是以上情况时使用。

Spring 6【Lombok、基于注解方式的IoC】(六)-全面详解(学习总结---从入门到深化)_第7张图片

 小提示: 这些注解没有功能上的区别,所以不按照上面位置去使用也能出效果。 但是为了提升代码规范,方便自己,方便他人,还是按照对应语义去使用会更好。

4.@Value注解 

IoC容器内一般不放简单数据类型的Bean。所以类中属性如果是简单数据类型,在使用注解方式配置 Bean时,直接给属性赋予默认值就可以了。

@Component
@Data
public class Person {
     /*
       等效于:
       
           
       
      */
      private String name="smallming";
}

 像这种简单数据类型,在Spring框架中唯一一种能见到的注入属性方式就是使用@Value注解。 @Value注解作用:

1、读取Spring容器中properties文件某个key对应的value值

2、对value值做类型转换,并赋值给属性中

根据上面作用可以看出来,我们首先必须要让IoC容器能读取一个properties文件。 假设:我们在src/main/resources下新建 test.properties文件,并在文件中添加二组键值对

Spring 6【Lombok、基于注解方式的IoC】(六)-全面详解(学习总结---从入门到深化)_第8张图片 

然后在Spring配置文件中,告诉Spring框架去加载这个属性文件。 

如果不想使用配置文件方式,也可以在类上添加@PropertySource注解,来加载属性文件

@Component
@PropertySource("test.properties")
@Data
public class Person {

语法为:@Value("${ key 的名称 }") ,如果没有${}将表示固定字符串。

@Component
@Data
public class Person {
     @Value("${mykey}")
     String content;
     @Value("${myage}")
     int age; // 由Spring框架做类型转换
}

5.@Autowired 注解实现Bean注入

本小节内容其实就是注解方式实现如何把Bean注入到当前实例。

@Autowired功能是从IoC容器中把其他Bean注入进来。有以下特点:

1、必须保证当前类被IoC容器管理,无论是XML方式还是注解方式都可以。否则@Autowire无效。

2、默认按照byType注入,如果有多个相同类型按照属性名称byName注入。

3、如果属性名和IoC容器中Bean的名称不一致,可以结合@Qualifier注解一起使用

5.1 测试@Autowired效果

创建一个学生类,并放入到IoC容器中。

@Component
public class Student {}

创建一个老师类,类中包含学生属性。使用@Autowired注解注入

@Data
@Component
public class Teacher {
    @Autowired
    private Student stu;
}

测试效果

@Test
void annotion(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext-annotation.xml");
        Teacher teacher = ac.getBean("teacher", Teacher.class);
        System.out.println(teacher);
}

发现输出结果中,Teacher中stu属性已经被注入了。

Spring 6【Lombok、基于注解方式的IoC】(六)-全面详解(学习总结---从入门到深化)_第9张图片

5.2 测试@Autowired注入方式 

在配置文件中再配置一个bean.(注:目前所学,使用注解没有办法给一个类配置两个Bean,只能结合 XML)

 再次运行会报错。控制台提示,无法注入,希望有一个Student类型,但是发现了两个,分别叫做 student,stu2

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type 'com.tong.annotation.Student' available: expected single
matching bean but found 2: student,stu2
at
org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(D
ependencyDescriptor.java:218)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDe
pendency(DefaultListableBeanFactory.java:1383)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDepe
ndency(DefaultListableBeanFactory.java:1325)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcesso
r$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.j
ava:709)
... 86 more

 如果修改Teacher中属性名为student或stu2,会发现又可以成功注入了。

5.3 测试@Qualifier注解

如果不希望Teacher中Student属性名和IoC容器中Bean的名称相同,可以使用@Qualifier注解指定需要 注入的Bean名称。

@Data
@Component
public class Teacher {
    @Autowired
    @Qualifier("stu2")
    private Student stu;
}

 6.@Resource注解实现Bean注入

@Resource注解是JPA中的注解,也能够实现注入属性的功能。JPA是Java EE规范中一项。所以JPA并没 有包含在JDK中,需要额外导入依赖。

所以在老版本Spring中想要使用@Resource注解,必须保证项目中包含依赖


    javax.annotation
    javax.annotation-api
    1.3.2

从Java EE 8 开始Oracle把Java EE规范标准交给Eclipse基金会去维护,并更名为Jakarta EE。 Spring 6 默认使用Jakarta EE 9作为标准。所以在当前版本中需要添加jakarta.annotation-api依赖


    jakarta.annotation
    jakarta.annotation-api
    2.1.1

 并且在使用时,需要导入的包由之前javax.annotation.Resource的换成jakarta.annotation.Resource

package com.tong.annotation;
import jakarta.annotation.Resource;
import lombok.Data;
import org.springframework.stereotype.Component;

@Data
@Component
public class Teacher {
       @Resource
       private Student stu;
}

@Resource特性:

1、默认按照属性名称byName方式去找。如果byName找不到按照byType。逻辑或关系。

2、如果只指定type属性,优先按照byType去找,如果找到多个,按照属性名byName去找。逻辑或关系。

3、如果只指定name属性,则固定按照name属性值去byName找。此时和属性名无关。

4、如果type和name都指定,则都生效。先byType确定范围,再byName从里面找符合条件的。都配 置时是一种逻辑与的关系。

 

你可能感兴趣的:(Spring全家桶,java,开发语言,spring,后端)