• Spring注解开发


    注解实现配置文件

    通过注解的方式就只能以实体类的形式进行配置了,我们在要作为配置的类上添加`@Configuration`注解

    1. @Configuration
    2. public class Config {
    3. }

    等价于

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans
    5. https://www.springframework.org/schema/beans/spring-beans.xsd">
    6. beans>

    在xml中我们是直接在配置文件中编写Bean的一些信息,现在在配置类中,我们只需要编写一个方法,并返回我们要创建的Bean的对象即可,并在其上方添加`@Bean`注解

    1. @Configuration
    2. public class Config {
    3. @Bean
    4. public Student student() {
    5. return new Student();
    6. }
    7. }

    还可以继续添加`@Scope`注解来指定作用域

    1. @Bean
    2. @Scope("prototype")
    3. public Student student() {
    4. return new Student();
    5. }

    可以在对象创建时做很多额外的操作,包括一些属性值的配置,接着我们就可以在主方法中加载此配置类,并创建一个基于配置类的容器

    1. public static void main(String[] args) {
    2. //使用AnnotationConfigApplicationContext来实现注解配置
    3. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
    4. Config.class
    5. );
    6. Student student = context.getBean(Student.class);
    7. System.out.println(student);
    8. }

    Bean的默认名称实际上就是首字母小写的方法名称,我们也可以手动指定

    1. @Bean("zzp")
    2. public Student student() {
    3. return new Student();
    4. }

    还可以直接在类上添加`@Component`注解来将一个类进行注册(现在最常用的方式),不过要实现这样的方式,我们需要添加一个自动扫描,来告诉Spring需要在哪些包中查找我们提供`@Component`声明的Bean。

    只需要在配置类上添加一个`@ComponentScan`注解即可,如果要添加多个包进行扫描,可以使用`@ComponentScans`来批量添加。

    1. @ComponentScan("edu.cafus.bean")
    2. @Configuration
    3. public class Config {
    4. }

    在Student类的上面添加`@Component`注解,来表示此类型需要作为Bean交给容器进行管理:

    同样的,在类上也可以直接添加`@Scope`来限定作用域

    1. @Component
    2. @Scope("prototype")
    3. public class Student {
    4. private String num;
    5. private int grade;
    6. }

    与`@Component`同样效果的还有`@Controller`、`@Service`和`@Repository`

    实现自动注入

    先将Person类也注册为Bean,在需要注入的位置,添加一个`@Resource`注解来实现自动装配

    1. @Component
    2. public class Student {
    3. private String num;
    4. private int grade;
    5. @Resource
    6. private Person person;
    7. }

    这样的好处是,我们完全不需要创建任何的set方法,只需要添加这样的一个注解就可以了,Spring会跟之前配置文件的自动注入一样,在整个容器中进行查找,并将对应的Bean实例对象注入到此属性中,当然,如果还是需要通过set方法来注入,可以将注解添加到方法上

    1. @Component
    2. public class Student {
    3. private String num;
    4. private int grade;
    5. private Person person;
    6. @Resource
    7. public void setPerson(Person person) {
    8. this.person = person;
    9. }
    10. }

    除了使用`@Resource`以外,我们还可以使用`@Autowired`(IDEA不推荐将其使用在字段上,会出现黄标,但是可以放在方法或是构造方法上),它们的效果是一样的,但是它们存在区别

    * @Resource默认**ByName**如果找不到则**ByType**,可以添加到set方法、字段上。

    * @Autowired默认是**byType**,可以添加在构造方法、set方法、字段、方法参数上。

    @Autowired`可以配合`@Qualifier`使用,来指定一个名称的Bean进行注入

    1. @Autowired
    2. @Qualifier("sxc")
    3. public void setCard(Card card) {
    4. System.out.println("通过方法");
    5. this.card = card;
    6. }

    如果Bean是在配置文件中进行定义的,我们还可以在方法的参数中使用`@Autowired`来进行自动注入

    1. @Configuration
    2. public class MainConfiguration {
    3. @Bean
    4. public Student student(@Autowired Card card){
    5. Student student = new Student();
    6. student.setCard(card);
    7. return student;
    8. }
    9. }

    通过`@PostConstruct`注解来添加构造后执行的方法,它等价于`init-method`

    1. @PostConstruct
    2. public void init(){
    3. System.out.println("我是初始化方法!1");
    4. num = "2";
    5. }

    执行顺序:Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct

    销毁方法可以使用`@PreDestroy`注解

    现有两种通过注解进行Bean声明的方式

    * 如果要注册为Bean的类是由其他框架提供,我们无法修改其源代码,那么我们就使用第一种方式进行配置。

    * 如果要注册为Bean的类是我们自己编写的,我们就可以直接在类上添加注解,并在配置中添加扫描。

    注解实现AOP操作

    首先我们需要在主类添加`@EnableAspectJAutoProxy`注解,开启AOP注解支持

    1. @EnableAspectJAutoProxy
    2. @ComponentScans({
    3. @ComponentScan("edu.cafus.aop"),
    4. @ComponentScan("edu.cafus.bean")
    5. })
    6. @Configuration
    7. public class Config {
    8. }

    接着我们只需在定义AOP增强操作的类上添加`@Aspect`注解和`@Component`将其注册为Bean即可,就像我们之前在配置文件中也要将其注册为Bean

    1. @Aspect
    2. @Component
    3. public class AopTest {
    4. }

    直接在里面编写方法,并将此方法添加到一个切点中,比如我们希望在Student的test方法执行之前执行我们的方法

    1. public int test(String str){
    2. System.out.println("我被调用了:"+str);
    3. return str.length();
    4. }

    只需要添加`@Before`注解即可

    1. @Before("execution(* com.test.bean.Student.test(..))")
    2. public void before(){
    3. System.out.println("我是之前执行的内容!");
    4. }

    同样的,我们可以为其添加`JoinPoint`参数来获取切入点信息

    1. @Before("execution(* com.test.bean.Student.test(..))")
    2. public void before(JoinPoint point){
    3. System.out.println("参数列表:"+ Arrays.toString(point.getArgs()));
    4. System.out.println("我是之前执行的内容!");
    5. }

    使用`@AfterReturning`注解来指定方法返回后的操作

    1. @AfterReturning(value = "execution(* com.test.bean.Student.test(..))", returning = "returnVal")
    2. public void after(Object returnVal){
    3. System.out.println("方法已返回,结果为:"+returnVal);
    4. }

    还可以指定returning属性,并将其作为方法某个参数的实参

    环绕也可以直接通过注解声明

    1. @Around("execution(* com.test.bean.Student.test(..))")
    2. public Object around(ProceedingJoinPoint point) throws Throwable {
    3. System.out.println("方法执行之前!");
    4. Object val = point.proceed();
    5. System.out.println("方法执行之后!");
    6. return val;
    7. }

    其他注解配置

    配置文件可能不止一个,我们有可能会根据模块划分,定义多个配置文件,这个时候,可能会出现很多个配置类,如果我们需要`@Import`注解来快速将某个类加入到容器中

    创建一个新的配置文件

    1. public class Test2Configuration {
    2. }
    1. @EnableAspectJAutoProxy
    2. @Configuration
    3. @ComponentScan("com.test")
    4. @Import(Test2Configuration.class)
    5. public class TestConfiguration {
    6. @Resource
    7. Connection connection;
    8. @PostConstruct
    9. public void init(){
    10. System.out.println(connection);
    11. }
    12. }

    注意另一个配置类并没有添加任何注解,实际上,相当于导入的类被强制注册为了一个Bean

    现在一共了解了三种注册为Bean的方式,利用这种特性,还可以将其他的类型也强制注册为Bean

    1. @EnableAspectJAutoProxy
    2. @Configuration
    3. @ComponentScan("com.test")
    4. @Import({Test2Configuration.class, Date.class})
    5. public class TestConfiguration {
    6. @Resource
    7. Connection connection;
    8. @Resource
    9. Date date;
    10. @PostConstruct
    11. public void init(){
    12. System.out.println(date+" -> "+connection);
    13. }
    14. }

    日期直接作为一个Bean放入到IoC容器中了,并且时间永远都是被new的那个时间,也就是同一个对象(因为默认是单例模式)

    通过`@Import`方式最主要为了实现的目标并不是创建Bean,而是为了方便一些框架的`Registrar`进行Bean定义

  • 相关阅读:
    spring cloud与加密库jasypt(ulisesbocchio)冲突问题定位
    [羊城杯 2020]GMC
    security 会话并发管理
    webpack5 eslint插件使用
    《C和指针》读书笔记(第十四章 预处理器)
    服务监控(四)之SpringBoot整合Prometheus
    06 ts扩展知识
    【网络安全】SSL Pinning及其绕过
    Multimodal-intersection-analysis-MIA-/ github
    C++之字符串语法
  • 原文地址:https://blog.csdn.net/weixin_51992178/article/details/126918456