Spring-ioc-注解配置

目录

一、引言

二、项目部署:

2.1创建maven项目:

2.2 添加Spring依赖:

2.3 创建Spring配置文件:

2.4 声明使用注解配置:

三、常见注解:

3.1 @Component、@Service、@Controller、@Resository

3.2 @Scope

3.3 @Lazy

3.4 @Postconstruct

3.5 @PerDestory

3.6 @AutoWired

3.7 @Resource

四、总结:


一、引言:

        Spring-ioc的使用,需要我们通过xml将类声明给spring容器进行管理,从而通过spring工厂完成对象的创建及属性值的注入。spring除了基于xml的配置方式,同时提供了注解的配置,直接在实体类添加注解声明给spring容器进行管理,以简化开发步骤

二、项目部署:

2.1 创建maven项目:

        使用web模板创建即可,此步骤略~      

2.2 添加spring依赖:

        maven工程中我们不再需要一个个进行jar的手动导入,只需要在pom.xml文件中添加依赖即可,jar包就会进行自动导入,在spring中,我们共需要五个包,我们只需要添加一个依赖即可“spring-context”,其他四个会自动添加部署项目中,所需的依赖可以到maven仓库中进行查找,网址:https://mvnrepository.com,具体代码如下:

 <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.18</version>
    </dependency>

       添加后,在项目的右侧菜单中,在maven project的dependencies可以查看导入的jar包,是否导入成功,添加成功后如图所示:

 2.3 创建spring配置文件

        因为spring容器初始化时,只会加载applicationContext.xml主配置文件,那么我们在实体类中添加的注解就不会被spring扫描,所以我们需要在applicationContext.xml配置文件声明spring的扫描范围,以此达到spring初始化时扫描带有注解的实体类并完成初始化操作,在之前的项目中我们添加过一次applicationContext.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"
       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>

2.4 声明使用注解配置 

        配置文件声明spring的扫描范围后,我们还需要声明使用注解配置,并声明spring容器注解的扫描范围~具体实现代码如下:

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

    <!--声明使用注解配置-->
    <Context:annotation-config/>
    <!--声明Spring工厂注解的扫描范围-->
    <context:component-scan base-package="com.xgsm.ioc.entity"/>

</beans>

三、常见注解:

3.1 @Component、@Service、@Controller、@Resository

        将实体类中添加@Component,即将该实体类交给spring容器进行管理;@Component中有value属性,当不添加的时候相当于id为实体类名的首字母小写,也可以自定义id,例如:设置id为“stu”:@Component(value=“stu”)或@Component(“stu”)value可以省略:

实体类:@Component无参数测试类
package com.xgsm.ioc.entity;

import org.springframework.stereotype.Component;

@Component
public class Student {
    private  int StuNum;
    private String StuName;
    private ClassRoom classRoom;

    public void setStuNum(int stuNum) {
        StuNum = stuNum;
    }

    public void setStuName(String stuName) {
        StuName = stuName;
    }

    public void setClassRoom(ClassRoom classRoom) {
        this.classRoom = classRoom;
    }
}
package com.xgsm.ioc.Test;

import com.xgsm.ioc.entity.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student);

    }
}

根据测试结果我们可以知道,此时spring已经为我们创建了对象,并将id设置“student”,即实体类名的首字母小写        

@Service、@Controller、@Resository和@Component有一个相同的功能就是,在类中声明该类注解,都是声明此类别spring容器进行管理,相当于applicationContext.xml主配置文件中的<bean>这个标签的作用;他们之间的区别有以下几点:

  • @Controller注解主要是声明将控制类配置给Spring管理,例如servlet
  • @Service注解主要是声明业务处理类配置给spring管理,例如Service
  • @Repository注解主要声明持久化类配置给spring管理,例如Dao接口
  • @Component除了控制器、service和Dao之外的类一律使用此注解

3.2 @Scope 

        @Scope 是类注解,用于声明当前类是单例模式还是非单例模式,相当于bean标签的Scope属性,@Scope (“prototype”)表示当前类为非单例模式,默认为单例模式

实体类@Scope (“prototype”)非单例模式测试类
package com.xgsm.ioc.entity;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;


@Component
@Scope("prototype")
public class Student {
    private  int StuNum;
    private String StuName;
    private ClassRoom classRoom;

    public void setStuNum(int stuNum) {
        StuNum = stuNum;
    }

    public void setStuName(String stuName) {
        StuName = stuName;
    }

    public void setClassRoom(ClassRoom classRoom) {
        this.classRoom = classRoom;
    }
}
package com.xgsm.ioc.Test;

import com.xgsm.ioc.entity.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        Student student = (Student) context.getBean("student");
        Student student1 = (Student) context.getBean("student");
        System.out.println(student);
        System.out.println(student1);

    }
}

        从测试结果中可以看到,由于这里我们采取的非单例模式,所以student和student1的值并不相同

3.3 @Lazy

        @Lazy 类注解,用于声明一个单例模式的bean是否为“懒汉模式”,@Lazy(true)表示声明为懒汉模式

 

实体类@Lazy(true)懒汉模式测试类
package com.xgsm.ioc.entity;

import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
@Lazy(true)
public class Student {
    private  int StuNum;
    private String StuName;
    private ClassRoom classRoom;

    public Student() {
        System.out.println("无参构造器");
    }

    public void setStuNum(int stuNum) {
        StuNum = stuNum;
    }

    public void setStuName(String stuName) {
        StuName = stuName;
    }

    public void setClassRoom(ClassRoom classRoom) {
        this.classRoom = classRoom;
    }
}
package com.xgsm.ioc.Test;

import com.xgsm.ioc.entity.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        Student student = (Student) context.getBean("student");

        System.out.println(student);


    }
}

        根据测试结果我们可以不难看出,懒汉模式是在实例化之后,创建对象的

 3.4 @Postconstruct

        @Postconstruct是方法注解,声明一个方法为当前类的初始化方法(在构造器之后执行),相当于bean标签的init-method属性

package com.xgsm.ioc.entity;

import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
@Scope("prototype")
@Lazy(true)
public class Student {
    private  int StuNum;
    private String StuName;
    private ClassRoom classRoom;

    public Student() {
        System.out.println("无参构造器");
    }
    @PostConstruct
    public  void  init(){
        System.out.println("----init-----");
    }

    public void setStuNum(int stuNum) {
        StuNum = stuNum;
    }

    public void setStuName(String stuName) {
        StuName = stuName;
    }

    public void setClassRoom(ClassRoom classRoom) {
        this.classRoom = classRoom;
    }
}

        根据测试类,可以看到方法是在构造器之后执行的

  3.5 @PreDestory

        @PreDestory注解是方法注解,声明一个方法为当前类的销毁方法,在对象容器中释放之前执行,相当于bean标签中的destory-method属性,此方法没办法测试,一般使用此方法可以实现关闭数据连接等操作~

package com.xgsm.ioc.entity;

import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
@Scope("prototype")
@Lazy(true)
public class Student {
    private  int StuNum;
    private String StuName;
    private ClassRoom classRoom;

    public Student() {
        System.out.println("无参构造器");
    }
    @PostConstruct
    public  void  init(){
        System.out.println("----init-----");
    }
    public  void  destory(){
        System.out.println("-----destory----");
    }

    public void setStuNum(int stuNum) {
        StuNum = stuNum;
    }

    public void setStuName(String stuName) {
        StuName = stuName;
    }

    public void setClassRoom(ClassRoom classRoom) {
        this.classRoom = classRoom;
    }
}

3.6 @Autowired

       @Autowired是属性注解,声明当前属性自动装配,默认是bytype,默认必须(如果没有找到类型与属性类型匹配的bean则会抛出异常);@Autowired(require=false)设置当前自动装配是否为必须,默认是必须

实体类-@Autowired自动装配测试类
package com.xgsm.ioc.entity;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
@Scope("prototype")
@Lazy(true)
public class Student {
    private  int StuNum;
    private String StuName;
    private ClassRoom classRoom;

    public Student() {
        System.out.println("无参构造器");
    }
    @PostConstruct
    public  void  init(){
        System.out.println("----init-----");
    }
    public  void  destory(){
        System.out.println("-----destory----");
    }

    public void setStuNum(int stuNum) {
        StuNum = stuNum;
    }

    public void setStuName(String stuName) {
        StuName = stuName;
    }

@Autowired
    public void setClassRoom(ClassRoom classRoom) {
        this.classRoom = classRoom;
    }

    public ClassRoom getClassRoom() {
        return classRoom;
    }
}
package com.xgsm.ioc.Test;

import com.xgsm.ioc.entity.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        Student student = (Student) context.getBean("student");

        System.out.println(student.getClassRoom());


    }
}

        当不把ClassRoom交给spring容器管理时,此时对setClassRoom()方法使用自动装配,会报错,因为通过类型匹配不到ClassRoom,就会派出异常

        异常处理,只需要将实体类ClassRoom交给spring容器管理即可,在ClassRoom实体类中使用@Component注解,即问题可解~

package com.xgsm.ioc.entity;

import org.springframework.stereotype.Component;


@Component
public class ClassRoom {
}

        测试类执行结果,打印Student类中的classRoom的值

         除此之前,使用@Autowired自动装配我们还可以在set方法中使用@Qualifier("id名"),来通过“id”名进行查找自动装配,如果找不到则会抛异常,所以需要在ClassRoom实体类中,给@Component(“”)赋值

package com.xgsm.ioc.entity;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * Description: Spring-Ioc-demo02
 * Created by WuHuaSen .
 * Created Date:  2022/4/13 16:31
 * Version:  V1.0
 */
@Component
@Scope("prototype")
@Lazy(true)
public class Student {
    private  int StuNum;
    private String StuName;
    private ClassRoom classRoom;

    public Student() {
        System.out.println("无参构造器");
    }
    @PostConstruct
    public  void  init(){
        System.out.println("----init-----");
    }
    public  void  destory(){
        System.out.println("-----destory----");
    }

    public void setStuNum(int stuNum) {
        StuNum = stuNum;
    }

    public void setStuName(String stuName) {
        StuName = stuName;
    }
@Autowired
    public void setClassRoom(@Qualifier("clazzroom") ClassRoom classRoom) {
        this.classRoom = classRoom;
    }

    public ClassRoom getClassRoom() {
        return classRoom;
    }
}

 3.6 @Resource

        @Resource是属性注解,也用于声明属性的自动装配,默认装配方式为byName,如果根据byName没有找到对应的Bean,则继续通过ByType寻找对应的Bean,或者根据Bytype找到的bean不止一个,那么也会抛出异常

package com.xgsm.ioc.entity;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * Description: Spring-Ioc-demo02
 * Created by WuHuaSen .
 * Created Date:  2022/4/13 16:31
 * Version:  V1.0
 */
@Component
@Scope("prototype")
@Lazy(true)
public class Student {
    private  int StuNum;
    private String StuName;
    private ClassRoom classRoom;

    public Student() {
        System.out.println("无参构造器");
    }
    @PostConstruct
    public  void  init(){
        System.out.println("----init-----");
    }
    public  void  destory(){
        System.out.println("-----destory----");
    }

    public void setStuNum(int stuNum) {
        StuNum = stuNum;
    }

    public void setStuName(String stuName) {
        StuName = stuName;
    }
@Resource
    public void setClassRoom(ClassRoom classRoom) {
        this.classRoom = classRoom;
    }

    public ClassRoom getClassRoom() {
        return classRoom;
    }
}

四、总结: 

        用了注解之后,就不需要在xml文件中配置了,Spring提供了几个辅助类会自动扫描和装配这些Bean。所以使用注解能大大减少xml文件的体积,Spring启动时会根据配置去扫描某些包里的类,得到类或方法上的注解,不同的注解会进行不同的操作。

优点:

1、节省配置,减少配置文件大小

2、编译时即可查看正确与否,提高效率

缺点:

1、增加了程序的耦合性,因为注解保存在class文件中,而且比较分散若要对配置进行修改需要重新编译

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暇光曙墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值