当前位置: 首页 > news >正文

Spring框架学习(中)

目录

1. DI注入的几种方式

1.1  Set方法注入

 1.2 构造器方法注入

2. spring常用注解

1. 组件扫描与依赖注入

2. 配置相关

3. AOP相关注解

4. 事务管理注解

5.  @Configuration注解

6.  @Component

7. @Repository

8. @Service 

9. @Autowire

10. 测试注解

AAC AnnotationConfigApplicationContext


1. DI注入的几种方式

1.1  Set方法注入

1. service层

package com.v.service;

import com.v.dao.EnrolledDao;

/**
 * 假设此类是:
 * 实训系统报名类service层的实现类
 */
public class EnrolledServiceImp {
    /**
     * 假设此方法是报名系统的报名业务逻辑处理方法
     * 此方法中需要调用到dao层的报名添加记录方法
     */
    EnrolledDao enrolledDao;// 单单从代码层面来看,此时enrolledDao为null,并没有实例化
    public void baoming(){
        enrolledDao.register();// 调用dao层对报名表添加记录的方法
    }

    /**
     * 此方法是我自动生成的,用于使用spring完成set方式注入对象
     * @param enrolledDao
     */
    public void setEnrolledDao(EnrolledDao enrolledDao) {
        this.enrolledDao = enrolledDao;
    }
}

 2. dao层

package com.v.dao;

/**
 * 假设此类是:
 * 实训报名类的dao层实现类
 */
public class EnrolledDao {
    /**
     * 假设此方法是dao层报名方法
     * 在此方法里面写对报名表的添加记录操作
     * @return
     */
    public boolean register(){
        // 这里写对报名表的插入操作代码....
        System.out.println("报名成功!");
        return true;
    }
}

 我们现在需要在service层的EnrolledServiceImp中,自动创建dao层的EnrolledDao。于是在EnrolledServiceImp,写一个dao的set方法。

3. 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--把EnrolledServiceImp交给spring管理-->
    <bean id="enrolledServiceImp" class="com.frank.service.EnrolledServiceImp">

    <!--ref是被注入类的 id-->
        <property name="enrolledDao" ref="enrolledDao"></property>
    </bean>

    <!--把EnrolledDao交给spring管理-->
    <bean id="enrolledDao" class="com.frank.dao.EnrolledDao"></bean>
</beans>

 4. 测试类

import com.v.service.EnrolledServiceImp;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 此类用于测试说明spring set方式注入对象是否成功
 */
public class TestApp {
    public static void main(String[] args) {

        // 1、因为我要找容器要对象,不是自己手动去new对象,所以先要创建容器对象
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
        // 2、容器对象有了,我怎么拿到我想要的对象呢?通过getbean方法得到,用参数指定要的对象的名字
        EnrolledServiceImp enrolledServiceImp = (EnrolledServiceImp) app.getBean("enrolledServiceImp");
        // 3、拿到了我想要的对象,为了测试是否成功,我调用一下里面的方法,如果控制台有打印说明成功
        enrolledServiceImp.baoming();// baoming方法中调用了dao层的register方法,控制台输出的就是register方法里面打印的代码执行了
    }
}

 1.2 构造器方法注入

还是以set方式注入的代码为例;使用构造器方式注入的话只需要改变两个地方即可:

一:把set方法改成带参的构造方法;

二:把bean.xml里面的<property>标签换成<constructor-arg>标签

1、 在Service层中

package com.v.service;

import com.v.dao.EnrolledDao;

/**
 * 假设此类是:
 * 实训系统报名类service层的实现类
 */
public class EnrolledServiceImp {
    /**
     * 假设此方法是报名系统的报名业务逻辑处理方法
     * 此方法中需要调用到dao层的报名添加记录方法
     */
    EnrolledDao enrolledDao;// 单单从代码层面来看,此时enrolledDao为null,并没有实例化
    public void baoming(){
        enrolledDao.register();// 调用dao层对报名表添加记录的方法
    }

    /**
     * 此方法是我自动生成的,用于使用spring完成set方式注入对象
     * @param enrolledDao
     */
    public EnrolledServiceImp (EnrolledDao enrolledDao) {
        this.enrolledDao = enrolledDao;
    }

      //无参构造必须要写

      public EnrolledServiceImp (){}
}

 2、 在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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--把EnrolledServiceImp交给spring管理-->
    <bean id="enrolledServiceImp" class="com.v.service.EnrolledServiceImp">

    <constructor-arg ref="enrolledDao"/>

   </property>
    </bean>

    <!--把EnrolledDao交给spring管理-->
    <bean id="enrolledDao" class="com.v.EnrolledDao"></bean>

    
</beans>

2. spring常用注解

spring注解是一个非常非常非常好用的工具,如果你用过一次,你就会彻底的爱上这个注解,这些注解可以让我们不用写xml文件了

1. 组件扫描与依赖注入

  • @Component - 通用组件注解,标记类为Spring管理的组件
  • @Repository - 标记数据访问层(DAO)组件
  • @Service - 标记业务服务层组件
  • @Controller - 标记表现层组件(如MVC控制器)
  • @Autowired - 自动装配依赖
  • @Qualifier - 与@Autowired配合使用,指定具体要注入的bean
  • @Resource - JSR-250提供的依赖注入注解
  • @Inject - JSR-330提供的依赖注入注解

2. 配置相关

  • @Configuration - 标记类为配置类
  • @Bean - 在配置类中声明一个bean
  • @Import - 导入其他配置类
  • @ComponentScan - 配置组件扫描的路径
  • @Profile - 指定bean在特定环境下激活

3. AOP相关注解

  • @Aspect - 声明一个切面类
  • @Pointcut - 定义切点表达式
  • @Before@After@Around@AfterReturning@AfterThrowing - 定义通知类型

4. 事务管理注解

  • @Transactional - 声明事务
  • @EnableTransactionManagement - 启用注解驱动的事务管理

5.  @Configuration注解

将spring.xml文件替换为一个SpringConfig类

每次使用xml文件都要记住一大堆的标签,肯定会觉得很麻烦,虽然写得多了也就习惯了,但是能让代码更简单一点何乐而不为呢

首先,创建一个SpringConfig类,然后在类名上,写一个@Configuration,就结束了

package com.v.config;
import org.springframework.context.annotation.Configuration;
@Configuration
//注解扫描整个包
@ComponentScan("com.v")
public class SpringConfig {
}

这个就相当于spring.xml文件了,@Configuration是声明spring的配置类

6.  @Component

可以替代<bean>标签,在需要被spring容器管理的实体类上写入@Component

package com.v.pojo;
import org.springframework.stereotype.Component;
@Componen("student")
public class Student {private String name;private int age;}

7. @Repository

可以替代<bean>标签,在需要被spring容器管理的数据管理层(Dao层)上写入@Repository

package com.v.config.dao;
import org.springframework.stereotype.Repository;
@Repository("studentDao")
public class StudentDao {
}

8. @Service 

可以替代<bean>标签,在需要被spring容器管理的业务层(Service层)上写入@Service 

@Service("studentService")
public class StudentService {@Autowiredprivate StudentDao studentDao;@Autowiredprivate Student student;

9. @Autowire

可以自动注入到其他类里

@Service("studentService")
public class StudentService {@Autowiredprivate StudentDao studentDao;@Autowiredprivate Student student;

10. 测试注解

我将以完整的代码进行测试,这段代码复制粘贴就能用。

com.v.config包下的spring配置类

package com.v.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.v")
public class SpringConfig {
}

com.v.service包下的业务层

package com.v.service;
import com.v.dao.StudentDao;
import com.v.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("studentService")
public class StudentService {@Autowiredprivate StudentDao studentDao;@Autowiredprivate Student student;public Student getStudent() {return student;}public void setStudent(Student student) {this.student = student;}public StudentDao getStudentDao() {return studentDao;}public void setStudentDao(StudentDao studentDao) {this.studentDao = studentDao;}
}

 com.v.dao包下的数据持久层

package com.v.dao;
import org.springframework.stereotype.Repository;
@Repository("studentDao")
public class StudentDao {
}

 com.v.pojo包下的实体类

package com.v.pojo;
import org.springframework.stereotype.Component;
@Component("student")
public class Student {private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +'}';}
}

main方法

import com.v.config.SpringConfig;
import com.v.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {@Autowiredprivate static StudentService studentService;public static void main(String[] args) {//解析SpringConfig类AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);studentService = (StudentService) context.getBean("studentService");System.out.println(studentService.getStudent());}
}

在解析的时候,那个解析类是很长的,我们可以记AAC AnnotationConfigApplicationContext

AAC AnnotationConfigApplicationContext

测试结果:

如果没有解析的话,结果如下 

这是经典空指针异常

相关文章:

  • 电子设备的“记忆大脑”:NAND、NOR、EEPROM谁在掌控你的数据?
  • 【防火墙 pfsense】2配置
  • 软件工程-进度管理-PERT图Gantt图
  • 力扣-141.环形链表
  • Python数据分析案例73——基于多种异常值监测算法探查内幕交易信息
  • 系统设计(1)—前端—CDN—Nginx—服务集群
  • conformer编码器
  • RFID使用指南
  • MODBUS转ProfiNet边缘计算网关驱动霍尼韦尔HPT温湿度仪表的动态控制闭环方案
  • Trae 实测:AI 助力前端开发,替代工具还远吗?
  • 2025年PTA天梯赛正式赛 | 算法竞赛,题目详解
  • 从 0 开始认识 WebSocket:前端实时通信的利器!
  • LabVIEW基于VI Server的控件引用操作
  • PTC加热片详解(STM32)
  • 代码随想录算法训练营day11(二叉树)
  • openwrt查询网关的命令
  • Android 14 系统统一修改app启动时图标大小和圆角
  • 解锁Linux共享内存:进程间通信的超高速通道(转)
  • 今日行情明日机会——20250425
  • 什么是CN2专线?全面解析中国电信的高性能网络服务
  • 吉林省公安厅出入境管理总队政委明志全已任省安保集团总经理
  • 春暖花开,为何皮肤却闹起了小情绪?
  • 从“网点适老化”到“社区嵌入式”,“金融为老上海模式”如何探索?
  • 在上海生活8年,13岁英国女孩把城市记忆写进歌里
  • 王庆成:儒家、墨家和洪秀全的“上帝”
  • 我国对国家发展规划专门立法