spring 学习 (注解)

发布于:2025-02-15 ⋅ 阅读:(9) ⋅ 点赞:(0)

目录

前言

常用的注解

须知

1 @Conponent注解

demo(案例)

2 @Controller+@Service+@Repository

demo(案例)

3 @Scope+@Lazy+@PostConstruct+@PreDestroy

demo(案例)

4 @Value+@Autowired+@Qualifier+@Resource

demo(案例)

5 @Configuration+@ComponentScan+@PropertySource+@import

demo(实例)


前言

之前学习 spring 框架时,我们知道实例化bean 都是依靠 spring 配置文件,在配置文件中书写一个个bean 标签,表示将要创建的对象。

本篇博客则是 使用注解的方式,平替之前使用 spring 配置文件创建对象,等操作。

Spring的注解可以代替xml配置;通俗点来讲,注解是对xml配置的平替;原先xml配置所实现的功能,现在可以使用注解实现;而且使用注解比xml配置更符合我们编码习惯,也更简单。

常用的注解

须知

以下任何demo(案例的前提)

即使我们使用各自注解代替 标签,属性啥的。但如何去解析 注解这是我们需要思考的。

以下在配置文件中写的 标签就是解析哪个包下的注解。

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

  <!--spring会去扫描fs包及其子包下所有的注解,并让其生效-->
<context:component-scan base-package="fs">
</context:component-scan>
</beans>

注意:

1 base-package 的属性值 是 你需要扫描哪个包下的注解

2 不要直接复制粘贴,看需要哪个补充哪个,否则很容易出问题。

3 当然了,这些最后同样会有相应注解替代 配置文件,扫描注解的标签。但需要注意任何注解的底层都是 以xml 配置文件的形式存在。


1 @Conponent注解

使用目的

@Conponent注解 就可以平替<bean>标签。

特别提醒:在使用spring注解的时候,要想使spring容器认识这些注解,我们需要在bean.xml文件中配置注解组件扫描,只有配置了组件扫描,spring才会去指定包下面扫描你使用了哪些注解,并让其生效。

	<!--spring会去扫描com.frank包及其子包下所有的注解,并让其生效-->
    <context:component-scan base-package="com.frank"></context:component-scan>

demo(案例)

使用 Conponent 注解 创建 person 类

person 类,Test 测试类

package fs.exerise;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
 @Component("person")
public class Person {
}
class Test{
    public static void main(String[] args) {
     ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
     Object bean = context.getBean("person");
     System.out.println(bean);
    }
}

效果展示

注意:component 注解里的值,可以理解为表示 之前在spring 配置文件 bean 标签的id 值。


2 @Controller+@Service+@Repository

我们在实际的开发过程中是按层来进行的;为了语义上面更加明确,所以衍生出来另外三个注解来代替@Conponent。他们的作用是为了在语义上更加明确。

@Controller注解:使用在Controller层的类上面

@Service注解:使用在Service层的类上面

@Repository注解:使用在Dao层的类上面


demo(案例)


3 @Scope+@Lazy+@PostConstruct+@PreDestroy

@Scope注解:平替<bean scope="">

@Lazy注解:平替<bean lazy-init="">

@PostConstruct注解:平替<bean init-method="">

@PreDestroy注解:平替<bean destroy-method="">


demo(案例)

UserController 类

package fs.controller;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
// 相当于本类 UserController 在 配置文件的 bean 标签
@Controller("user")
// scope 属性表示作用域
@Scope(value = "singleton")
public class UserController {

    public UserController() {
        System.out.println("创建UserController");
    }
    // @PostConstruct 注解表示初始化方法
@PostConstruct
    public void init () {
        System.out.println("UserController初始化");
    }
    // @PreDestroy 注解表示销毁方法
@PreDestroy
    public void destroy () {
        System.out.println("UserController销毁");
    }
}

Test 测试类

package fs.controller;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");
       UserController userController = (UserController) app.getBean("user");
// 关闭 spring 容器 
         
app.close();
    }

}

效果展示


4 @Value+@Autowired+@Qualifier+@Resource

平替bean标签注入时的标签

原先使用xml实现注入的时候使用的是<property>标签来指明注入的关系;现在我们可以通过下面的注解来替换它。

@value注解:使用在字段或者方法上面,用于注入普通数据

@Autowired注解:使用在字段或者方法上面,用于注入引用数据(默认按照byType方式进行注入)

@Qualifier注解:使用在字段或者方法上面,搭配@Autowired根据名称进行注入

@Resource注解:使用在字段或者方法上面,根据类型或者名称进行注入


demo(案例)

userController 类

package fs.controller;

import fs.service.UserService;
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.Controller;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
// 相当于本类 UserController 在 配置文件的 bean 标签
@Controller("user")
// scope 属性表示作用域
@Scope(value = "singleton")
public class UserController {
    @Autowired
    // @Autowired 注解表示自动注入 一般适用于 成员变量
// @Qualifier 可以为 @Autowired 注解的补充,表示注入的bean的id
    @Qualifier("userService")
    private UserService userService;
    // @Value 注解表示注入值
    @Value("dj")
    private  String name;
    public void a(){
        System.out.println(userService+"他的名字是"+name);
    }
    public UserController() {
        System.out.println("创建UserController");
    }
    // @PostConstruct 注解表示初始化方法
@PostConstruct
    public void init () {
        System.out.println("UserController初始化");
    }
    // @PreDestroy 注解表示销毁方法
@PreDestroy
    public void destroy () {
        System.out.println("UserController销毁");
    }
}

疑问:@Autowired注解是根据类型进行注入的,那如果我有多个UserDao类型呢?

答:所以这个时候@Qualifier注解的作用就起来了,它的作用是当发现你使用了@Autowired注解后,却有多个相同的类型,可以通过@Qualifier注解指定其中的一个名字进行注入(按名字注入)。

看案例:

我再新建一个UserDaoImp2类,让该类也去实现UserDao接口,重新观察 UserController 类

UserDaoImp1 类
package fs.Dao.impl;

import fs.Dao.UserDao;
import org.springframework.stereotype.Repository;

@Repository("UserDao1")
public class UserDaoImp1 implements UserDao {
}
UserDaoImpl2 类
package fs.Dao.impl;

import fs.Dao.UserDao;
import org.springframework.stereotype.Repository;

@Repository("UserDao2")
public class UserDaoImpl2 implements UserDao {
}

UserController 类

发现 ,因为存在 多个 userDao 的实现类,即使使用 Autowired 注解 也不知道 选择哪一个。

因此采取办法是 使用@Qualifier注解 选择其中一个 注入 进去

注意:@Resource注解:不给参数的时候相当于@Autowired进行注入;给了参数相当于@Autowired+@Qualifier


5 @Configuration+@ComponentScan+@PropertySource+@import

@Configuration 注解: 平替bean.xml文件

@ComponentScan 注解: 平替 <context:component-scan base-package="com.frank">

@PropertySource("jdbc.properties") 注解: 平替 <context:property-placeholder location="classpath:jdbc.properties">

@Import(MyDataSource.class)注解:平替 <import resource="classpath:">

注意:

bean.xml文件都被配置类给替换了,那么我在写测试类创建容器对象的时候就不能用

new ClassPathXmlApplicationContext(“bean.xml”)了;而是选择使用new AnnotationConfigApplicationContext(SpringConfig.class)。


demo(实例)

person 类

package fs.exerise;

import org.springframework.stereotype.Component;
 @Component("person")
public class Person {
}

扫描所写注解的类

package fs.exerise;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
// @Configuration 注解表示当前类是一个配置类,用来代替xml配置文件
@Configuration
// @ComponentScan 注解表示扫描包,用来代替xml配置文件
// basePackages 属性表示扫描的包
@ComponentScan(basePackages ="fs.exerise")
public class SpringConfigration {
}

Test 测试类

package fs.exerise;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfigration.class);
        Object bean = context.getBean("person");
        System.out.println(bean);
    }
}

效果展示