【Spring】Spring IoC annotation development

Based on the latest Spring framework tutorial of [Power Node], the first Spring 6 tutorial on the entire network, learn spring from scratch to advanced with Lao Du and Lao Du’s original notes https://www.yuque.com/docs/share/866abad4-7106 -45e7-afcd-245a733b073f?# "Spring6" is organized, document password: mg9b


Spring related articles are compiled and summarized at: https://www.yuque.com/u27599042/zuisie


  • Spring6 advocates full annotation development
  • Annotations exist primarily to simplify XML configuration.
  • An annotation is actually a mark

Review custom annotations

  • Meta-annotations: Annotations that annotate annotations
  • @Target annotation: used to modify the position where the annotation can appear
    • @Target(value = {ElementType.TYPE, ElementType.FIELD}), Target annotations can appear on classes or fields
    • @Target(value = {ElementType.TYPE}), Target annotation can appear on the class
  • When using an annotation, if the attribute name of the annotation is value, value can be omitted.
    • @Target({ElementType.TYPE})
  • When using an annotation, if the attribute value of the annotation is an array and there is only one element in the array, the curly braces can be omitted.
    • @Target(ElementType.TYPE)
  • @Retention: It is also a meta-annotation, used to mark when the annotation can be retained.
    • If the annotation is to be saved in the class file and can be read by the reflection mechanism, use @Retention(RetentionPolicy.RUNTIME)
    • @Retention(RetentionPolicy.SOURCE), indicating that the annotations of the Retention annotation can only be retained in the source file, and the annotations of the Retention annotation cannot be seen in the bytecode and runtime.
  • Custom annotations and defined annotation properties:
// 标注该注解可以用在类上
@Target(ElementType.TYPE)
// 标注@Component注解最终保留在class文件当中,并且可以被反射机制读取。
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
    
    

    // 定义注解的属性
    // String是属性类型
    // value是属性名
    String value();

    // 其他的属性
    // 属性类型String
    // 属性名是name
    //String name();

    // 数组属性
    // 属性类型是:String[]
    // 属性名:names
    //String[] names();

    //int[] ages();

    //int age();
}

Review the use of custom annotations

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
    
    
    String value();
}
@Component("user")
public class User {
    
    }

Get annotations via reflection

@org.junit.Test
public void testGetAnnotationByReflect() throws Exception{
    
    
    // 将类加载到JVM中
    Class<?> clazz = Class.forName("cw.study.spring.bean.User");
    // 判断类上是否有自定义的Component注解
    if (clazz.isAnnotationPresent(Component.class)) {
    
    
        // 如果有,获取该注解
        Component component = clazz.getAnnotation(Component.class);
        // 获取该类上注解的属性值
        System.out.println(component.value());
    }
}

image.png

Component scanning principle

  • Requirement: Given a package name, instantiate all classes annotated with @Component under this package.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
    
    
    String value();
}
@Component("user")
public class User {
    
    }

@Component("cat")
public class Cat {
    
    }

public class Person {
    
    }
@org.junit.Test
public void componentScan() {
    
    
    // 已知的包名如下,需要扫描包下所有的类,将有Component注解的类实例化
    String packageName = "cw.study.spring.bean";
    // 包名其实就是目录名,将包名转化为目录
    // . 在正则中代表任意字符,需要进行转义,而 \\ 表示 \ 所以使用 \\.
    String directoryName = packageName.replaceAll("\\.", "/");
    // 软件包是在类路径下的,所以可以使用系统加载器加载目录获取URL
    URL url = ClassLoader.getSystemClassLoader().getResource(directoryName);
    // 通过URL获取包对应的绝对路径
    String path = url.getPath();
    System.out.println("path = " + path);
    // 根据绝对路径创建目录对应的对象
    File file = new File(path);
    // 获取目录下的文件对象
    File[] files = file.listFiles();
    System.out.println(files.length);
    // 遍历每个文件对象
    Arrays.stream(files).forEach(f -> {
    
    
        try {
    
    
            // 获取文件名
            String fName = f.getName();
            // System.out.println("fName = " + fName);
            // 得到类名
            String className = packageName + "." + fName.split("\\.")[0];
            // 加载类到JVM
            Class<?> clazz = Class.forName(className);
            // 判断类上是否有Component注解
            if (clazz.isAnnotationPresent(Component.class)) {
    
    
                // 获取注解
                Component component = clazz.getAnnotation(Component.class);
                // 获取注解的属性(Bean的id)
                String id = component.value();
                System.out.println(id);
                // 实例化对象
                Object o = clazz.getDeclaredConstructor().newInstance();
                System.out.println(o);
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    });
}

Annotations for declaring beans

  • Annotations responsible for declaring Beans, including four common ones:
    • @Component: component
    • @Controller: controller
    • @Service: business
    • @Repository: warehouse (Dao)
  • Among the above four annotations, @Controller, @Service, and @Repository are all aliases of @Component (@AliasFor). In fact, the functions of these four annotations are the same. You can use any of them, but use different ones on beans with different purposes. Annotations can enhance program readability:
    • Normal bean: Component
    • Used on the controller class: Controller (control layer)
    • Used on service class: Service (business layer)
    • Used on dao class: Repository (persistence layer)
  • Among the four annotations above, there is only one value attribute, which is used to specify the id of the bean.
@Target({
    
    ElementType.TYPE}) // 只能使用在类上
@Retention(RetentionPolicy.RUNTIME) // 可以通过反射获取该注解
@Documented
@Indexed
public @interface Component {
    
    
    String value() default "";
}

@Target({
    
    ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
    
    
    // Component的别名
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

@Target({
    
    ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
    
    
    // Component的别名
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

@Target({
    
    ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
    
    
    // Component的别名
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

Use of Spring annotations

Step 1: Add aop dependencies

  • When the spring-context dependency is added, the aop dependency will be automatically associated.
  • image.png

Step 2: Add the context namespace to the configuration file

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

</beans>

Step 3: Specify the scanned packages in the configuration file

  • Specify the scanned packages in the configuration file and tell Spring where the packages that need to be scanned are located.
  • Spring will scan the classes in the specified package and the classes in its sub-packages. If the class is marked with an annotation that declares a bean, an instance of the class will be created and placed in the Spring container.
<?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需要进行扫描的包在什么位置 -->
	<context:component-scan base-package="cw.study.spring"/>
	
</beans>

Step 4: Use annotations on the Bean class

@Component("user")
public class User {
    
    }

@Controller("userController")
public class UserController {
    
    }

test

@org.junit.Test
public void test01() {
    
    
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Object user = applicationContext.getBean("user");
    Object userController = applicationContext.getBean("userController");
    System.out.println(user);
    System.out.println(userController);
}

image.png

important point

  • If the attribute name of the annotation is value, then value can be omitted.
  • If the value attribute is completely removed, spring will automatically name the Bean. The default name rule is: the first letter of the Bean class name can be lowercase.
@Component
public class User {
    
    }

@Controller
public class UserController {
    
    }

@org.junit.Test
public void test02() {
    
    
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Object user = applicationContext.getBean("user");
    Object userController = applicationContext.getBean("userController");
    System.out.println(user);
    System.out.println(userController);
}

image.png

  • If you want to scan multiple packages, there are two solutions:
    • The first one: Specify multiple packages in the configuration file, separated by commas.
<context:component-scan base-package="cw.study.spring.bean, cw.study.spring.controller"/>
  • Second type: Specify the common parent package of multiple packages.
    • Spring will scan classes in the specified package and classes in its sub-packages
    • Using this method will sacrifice some efficiency
<context:component-scan base-package="cw.study.spring"/>

Selective instantiation of beans

  • Selective instantiation of a bean means only selecting classes that meet certain conditions for bean instantiation, or excluding classes that meet certain conditions and not instantiating beans for these classes.
package cw.spring.bean;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

/**
 * ClassName: A
 * Package: cw.spring.bean
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 11:42
 * @Version 1.0
 */
@Component
public class A {
    
    
    public A() {
    
    
        System.out.println("A的无参数构造方法执行");
    }
}

@Controller
class B {
    
    
    public B() {
    
    
        System.out.println("B的无参数构造方法执行");
    }
}

@Service
class C {
    
    
    public C() {
    
    
        System.out.println("C的无参数构造方法执行");
    }
}

@Repository
class D {
    
    
    public D() {
    
    
        System.out.println("D的无参数构造方法执行");
    }
}

@Controller
class E {
    
    
    public E() {
    
    
        System.out.println("E的无参数构造方法执行");
    }
}

Method 1: **use-default-filters="false" + **context:include-filter

  • use-default-filters="false": Do not use spring's default instantiation rules, that is, all annotations with declared beans will be invalid, and beans annotated with Component, Controller, Service, and Repository will not be instantiated (let all The annotation of the declared bean is invalid)
    • The default value of use-default-filters is true
  • <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
    • Indicates that the bean annotated with the Component annotation is instantiated.
    • The type attribute is used to specify the type of condition for filtering the class, that is, what to filter based on, type="annotation", filtering based on the annotation of the class
    • The expression attribute is used to specify filtering conditions, expression="org.springframework.stereotype.Component", only classes annotated with the Component annotation are instantiated.
  • Since the other three annotations are just aliases of Component, including Component also includes the other three annotations.
  • Note: When using context:include-filter, the attribute value of use-default-filters must be false, otherwise context:include-filter is invalid.
<!-- 指定要进行扫描的包 -->
<context:component-scan base-package="cw.spring.bean" use-default-filters="false">
  <!-- 被 Component 注解标注的 bean 进行实例化 -->
  <!-- 由于其他三个注解只是 Component 的别名,所以包含 Component 也就包含其他三种注解 -->
  <!-- <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/> -->
  <!-- 被 Controller 注解标注的 bean 进行实例化 -->
  <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

Method 2: **use-default-filters=“true” + **context:exclude-filter

  • use-default-filters="true": Use spring's default instantiation rules, that is, all annotations with declared beans will take effect, and beans annotated with Component, Controller, Service, and Repository will be instantiated.
    • The default value of use-default-filters is true
  • <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/>
    • Indicates that beans annotated with Component annotations will not be instantiated, and beans annotated with Component annotations are excluded.
  • Since the other three annotations are just aliases of Component, excluding Component also excludes the other three annotations.
<!-- 指定要进行扫描的包 -->
<context:component-scan base-package="cw.spring.bean">
  <!-- 排除被 Component 注解标注的 bean,这些 bean 不参与实例化 -->
  <!-- 由于其他三个注解只是 Component 的别名,所以排除 Component 也就排除了其他三种注解 -->
  <!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/> -->
  <!-- 排除被 Controller 注解标注的 bean,这些 bean 不参与实例化 -->
  <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

Annotations responsible for injection

  • @Component @Controller @Service @Repository These four annotations are only used to declare beans. After declaration, these beans will be instantiated.
  • To assign values ​​to the properties of the Bean, use the following annotations:
    • @Value
    • @Autowired
    • @Qualifier
    • @Resource

@Value

  • for simple type injection
  • When the type of the attribute is a simple type, you can use the @Value annotation for injection.
  • @Value annotation is used instead of<property name="" value=""/>
@Target({
    
    ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
    
    
	String value();
}
used on attributes
  • @value can be written directly on the attribute without providing the corresponding set method.
package cw.spring.bean;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * ClassName: MyDataSource
 * Package: cw.spring.bean
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 12:13
 * @Version 1.0
 */
@Component
public class MyDataSource {
    
    
    @Value("com.mysql.cj.jdbc.Driver")
    private String driver;
    @Value("jdbc:mysql://localhost:3306/spring")
    private String url;
    @Value("root")
    private String username;
    @Value("123456")
    private String password;
    
    @Override
    public String toString() {
    
    
        return "MyDataSource{" + "driver='" + driver + '\'' + ", url='" + url + '\'' + ", username='" + username + '\'' + ", password='" + password + '\'' + '}';
    }
}
Used in set method
  • @value can also be written on the set method corresponding to the attribute to realize the injection of attribute value.
  • In order to simplify the code, the set method is generally not provided, and the @Value annotation is used directly on the attribute to complete the attribute assignment.
package cw.spring.bean;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * ClassName: MyDataSource
 * Package: cw.spring.bean
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 12:13
 * @Version 1.0
 */
@Component
public class MyDataSource {
    
    
    private String driver;
    private String url;
    private String username;
    private String password;
    
    @Value("com.mysql.cj.jdbc.Driver")
    public void setDriver(String driver) {
    
    
        this.driver = driver;
    }
    
    @Value("jdbc:mysql://localhost:3306/spring")
    public void setUrl(String url) {
    
    
        this.url = url;
    }
    
    @Value("root")
    public void setUsername(String username) {
    
    
        this.username = username;
    }
    
    @Value("123456")
    public void setPassword(String password) {
    
    
        this.password = password;
    }
    
    @Override
    public String toString() {
    
    
        return "MyDataSource{" + "driver='" + driver + '\'' + ", url='" + url + '\'' + ", username='" + username + '\'' + ", password='" + password + '\'' + '}';
    }
}
Used in formal parameters of constructor methods
  • @Value annotation can also be used on the formal parameters of the constructor method
package cw.spring.bean;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * ClassName: MyDataSource
 * Package: cw.spring.bean
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 12:13
 * @Version 1.0
 */
@Component
public class MyDataSource {
    
    
    private String driver;
    private String url;
    private String username;
    private String password;
    
    public MyDataSource(
            @Value("com.mysql.cj.jdbc.Driver") String driver, 
            @Value("jdbc:mysql://localhost:3306/spring") String url, 
            @Value("root") String username, 
            @Value("123123") String password
    ) {
    
    
        this.driver = driver;
        this.url = url;
        this.username = username;
        this.password = password;
    }
    
    @Override
    public String toString() {
    
    
        return "MyDataSource{" + "driver='" + driver + '\'' + ", url='" + url + '\'' + ", username='" + username + '\'' + ", password='" + password + '\'' + '}';
    }
}

@Autowired

  • @Autowired annotation is used to inject non-simple types .
    • Autowired: automatic wiring, or automatic assembly
    • @Autowired, automatic assembly through annotations
  • @Autowired annotation does not require set method
  • Using the @Autowired annotation alone , the default assembly is based on the type , that is, the default is byType. If you need to automatically assemble based on the name, you need to use the @Qualifier annotation.
  • The @Autowired annotation is automatically assembled based on the type. If you only use the @Autowired annotation, two instances of the same type cannot exist in the Spring container. If you want to use the @Autowired annotation and there are two instances of the same type in the Spring container, you need Use the @Qualifier annotation to assemble based on the name
  • This annotation can be marked on the constructor, method, formal parameter, attribute, annotation. The usage and writing position are the same as @Value.
  • This annotation has a required attribute, and the default value is true, which means that the injected Bean must exist during injection. If it does not exist, an error will be reported. If the required attribute is set to false, it means that it does not matter whether the injected bean exists or not. If it exists, it will be injected. If it does not exist, no error will be reported.
@Target({
    
    ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
    
    
    boolean required() default true;
}
  • When using the @Autowired annotation, you can use it directly without specifying any attributes.
/**
 * ClassName: OrderDao
 * Package: cw.spring.dao
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 12:50
 * @Version 1.0
 */
public interface OrderDao {
    
    
    void insert();
}
/**
 * ClassName: OrderDaoImplForMySQL
 * Package: cw.spring.dao.impl
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 12:50
 * @Version 1.0
 */
@Repository
public class OrderDaoImplForMySQL implements OrderDao {
    
    
    @Override
    public void insert() {
    
    
        System.out.println("MySQL数据库正在保存订单信息...");
    }
}
import cw.spring.dao.OrderDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * ClassName: OrderService
 * Package: cw.spring.service
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 12:49
 * @Version 1.0
 */
@Service("orderService")
public class OrderService {
    
    
    @Autowired
    private OrderDao orderDao;
    
    public void save() {
    
    
        orderDao.insert();
    }
}
  • When there is only one constructor in the class, and the parameters on the constructor and the attributes that need to be injected can correspond, the @Autowired annotation can be omitted. If there are multiple constructors, @Autowired cannot be omitted.
  • It is best not to omit it, the program will be more readable
/**
 * ClassName: OrderService
 * Package: cw.spring.service
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 12:49
 * @Version 1.0
 */
@Service("orderService")
public class OrderService {
    
    
    // @Autowired
    // @Qualifier("orderDaoImplForOracle")
    private OrderDao orderDao;
    
    public OrderService(OrderDao orderDao) {
    
    
        this.orderDao = orderDao;
    }
    
    public void save() {
    
    
        orderDao.insert();
    }
}

@Qualifier

  • The @Autowired annotation and the @Qualifier annotation are combined to assemble based on the name. The Bean name is specified in the @Qualifier annotation.
/**
 * ClassName: OrderDaoImplForOracle
 * Package: cw.spring.dao.impl
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 12:59
 * @Version 1.0
 */
@Repository
public class OrderDaoImplForOracle implements OrderDao {
    
    
    @Override
    public void insert() {
    
    
        System.out.println("Oracle数据库正在保存订单信息...");
    }
}
/**
 * ClassName: OrderService
 * Package: cw.spring.service
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 12:49
 * @Version 1.0
 */
@Service("orderService")
public class OrderService {
    
    
    @Autowired
    @Qualifier("orderDaoImplForOracle")
    private OrderDao orderDao;
    
    public void save() {
    
    
        orderDao.insert();
    }
}

@Resource

  • The @Resource annotation can complete non-simple type injection.
  • The @Resource annotation is in the JDK extension package, which means it is part of the JDK, while the @Autowired annotation is the Spring framework's own.
  • @Resource is in the JDK standard specification, it is more versatile and is more recommended.
  • The @Resource annotation is assembled byName according to the name by default. When the name is not specified, the attribute name is used as the name. If it cannot be found by name, assembly by type byType will be automatically started.
  • The @Resource annotation is used on properties, setter methods, and methods .
@Target({
    
    ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Resources.class)
public @interface Resource {
    
    
    String name() default "";

    String lookup() default "";

    Class<?> type() default Object.class;

    AuthenticationType authenticationType() default Resource.AuthenticationType.CONTAINER;

    boolean shareable() default true;

    String mappedName() default "";

    String description() default "";

    public static enum AuthenticationType {
    
    
        CONTAINER,
        APPLICATION;

        private AuthenticationType() {
    
    
        }
    }
}
  • The @Resource annotation belongs to the JDK extension package, so it is not included in the JDK. You need to introduce the following additional dependencies:
    • Introduce extended dependencies
    • If it is JDK8, there is no need to introduce additional dependencies. If it is higher than JDK11 or lower than JDK8, the following dependencies need to be introduced.
<dependency>
  <groupId>jakarta.annotation</groupId>
  <artifactId>jakarta.annotation-api</artifactId>
  <version>2.1.1</version>
</dependency>
<dependency>
  <groupId>javax.annotation</groupId>
  <artifactId>javax.annotation-api</artifactId>
  <version>1.3.2</version>
</dependency>
/**
 * ClassName: StudentDao
 * Package: cw.spring.dao
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 16:03
 * @Version 1.0
 */
public interface StudentDao {
    
    
    void deleteById();
}
/**
 * ClassName: StudentDaoImplForMySQL
 * Package: cw.spring.dao.impl
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 16:04
 * @Version 1.0
 */
@Repository
public class StudentDaoImplForMySQL implements StudentDao {
    
    
    @Override
    public void deleteById() {
    
    
        System.out.println("MySQL数据库正在删除学生信息...");
    }
}
/**
 * ClassName: StudentService
 * Package: cw.spring.service
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-14 16:05
 * @Version 1.0
 */
@Service
public class StudentService {
    
    
    // name属性用于指定将要被注入到该属性的Bean的名字
    @Resource(name = "studentDaoImplForMySQL")
    private StudentDao studentDao;
    
    public void delete() {
    
    
        studentDao.deleteById();
    }
}

Full annotation development

  • Full annotation development means no longer using spring configuration files and writing a configuration class to replace the configuration files.

@Configuration annotation annotates the configuration class

  • Configuration classes are annotated with the @Configuration annotation
@Configuration
public class Spring6Config {
    
    
}

@ComponentScan annotation configures the scanned package

  • Configure the packages to be scanned through the @ComponentScan annotation
@Configuration
@ComponentScan({
    
    "cw.spring.dao", "cw.spring.service"})
public class Spring6Config {
    
    
}

Obtain Spring container under full annotation development

  • Obtaining the spring container new ClassPathXmlApplicationContext()is no longer an object, butnew AnnotationConfigApplicationContext()
@org.junit.Test
public void test03() {
    
    
    // 获取Spring容器对象时,需要传配置类为参数
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Spring6Config.class);
    StudentService studentService = applicationContext.getBean("studentService", StudentService.class);
    studentService.delete();
}

Guess you like

Origin blog.csdn.net/m0_53022813/article/details/132058759