Spring框架

SpringDI(依赖注入)

🎗作用

将springioc容器所创建的各个组件,使用DI的语法进行关联,耦合(胶水)

⭐️一个类可注入多次,但id值必须唯一

🎗DI实现方式

  1. set注入

  2. 构造注入

  3. 注解注入

🎗DI数据类型

  1. 基本类型与String

  2. JavaBean

  3. 复杂类型,list set array map properties

🎗DI使用步骤

  1. 思考,什么方式,什么数据类型

  2. 给属性提供set(构造)方法

  3. 编写配置文件

🎗依赖注入示例

📖DI注入之set注入--三层架构(DI数据类型:JavaBean)

代码编写逻辑:

  • 1.创建各接口及各接口实现类,并写相关方法

  • 2.将需要spring管理的类注入spring容器

  • 在配置文件中,进行<property name="需注入的类属性名" ref="id唯一标识"></property>的编写

  • 3.采用DI依赖注入中的set方式进行注入,完善实现类中的setter方法

  • 5.编写测试类,加载核心配置文件,并调用getBean获取对象

📖DI注入之set注入(DI数据类型:基本类型与String类型)

代码编写逻辑:

  • 1.编写实体类,并生成set方法

  • 2.编写资源文件,给实体类属性赋值

  • 3.编写测试类

📖DI注入之set注入(DI数据类型:复杂类型)

代码编写逻辑:

  • 1.编写实体类,并生成set方法

  • 2.编写资源文件,给实体类属性赋值

 <!--  set注入之复杂类型  -->
     <bean id="animals" class="com.apesource.po.Animals">
         <property name="myList">
             <list>
                 <value>猫咪</value>
                 <value>狗狗</value>
                 <value>兔子</value>
                 <value>猪猪</value>
             </list>
         </property>
         <property name="array">
             <array>
                 <value>金丝猴</value>
                 <value>羚羊</value>
                 <value>朱鹮</value>
                 <value>熊猫</value>
             </array>
         </property>
         <property name="myMap">
             <map>
                 <entry key="猴子" value="吃香蕉"></entry>
                 <entry key="猫咪" value="吃小鱼干"></entry>
                 <entry key="狗狗" value="吃骨头"></entry>
             </map>
         </property>
         <property name="myProp">
             <props>
                 <prop key="成都">大熊猫</prop>
                 <prop key="汉中洋县">朱鹮</prop>
                 <prop key="秦岭">金丝猴</prop>
             </props>
         </property>
         <property name="mySet">
             <set>
                 <value>两栖动物</value>
                 <value>爬行动物</value>
                 <value>哺乳动物</value>
             </set>
         </property>
     </bean>
  • 3.编写测试类

📖DI注入之构造注入(DI数据类型:基本类型与String类型)

代码编写逻辑:

  • 1.编写实体类,并生成有参、无参构造方法

  • 2.编写资源文件,给实体类属性赋值(三种方式)

  • 3.编写测试类

📖DI注入之构造注入--三层架构
  • 1.创建各接口及各接口实现类,并写相关有参、无参方法

  • 2.编写资源文件

  • 3.编写测试类

bean实例化

通过构造方法(默认)

通过工厂方法

通过静态工厂方法

bean作用域

含义:spring对于创建javaBean实例的方式 ​

语法:<bean scope="属性值"></bean> ​

属性值: ​

singleton=====>单例(默认) ​

prototype=====>多例 ​

request=======>一个请求创建一个 ​

session=======>一个会话创建一个

bean生命周期

1.实例化 ​

2.属性赋值(DI) ​

3.初始化 ​

        3.1接口 InitializingBean ​

        3.2属性 init-method=“” ​

4.操作使用 ​

5.销毁了 ​

        5.1接口 DisposableBean

🎗注解

Spring2.5之后是(xml+annotation)

目的优化下面的代码

<bean id="" class="" init-method="" destroy-method="" scope="" autowire="">
             <property></property>
             <constructor-arg></constructor-arg>
</bean>
1️⃣注入类

@Component 语法:

@Component(value="注入容器中的id,如果省略id为类名且首字母小写,value属性名称可以省略"

@Repository = == = = > 注入数据访问层

@Service == = === ==> 注入业务层

@Controller = == ==> 注入控制层

2️⃣注入基本数据

@Value

  • 含义:注入基本数据

  • 替换:< property > < /property >

  • 修饰:成员变量或对应的set方法

  • 语法:

    • @Value("数据内容")

    • @Value("${动态获取}")

      xml配置文件

      <context:property-placeholder location="classpath:jdbc.properties">
      < /context:property-placeholder >

代码实现:

image-20240807000658181

//test.properties

 username=123456
 userpwd=131422
Student实体类,在属性写上@Value注解使用“${}”动态获取数据

 ​
 @Component
 public class Student {
     @Value("${username}")
     private String sname;
     @Value("${userpwd}")
     private int spwd;
 ​
     @Override
     public String toString() {
         return "Student{" +
                 "sname='" + sname + '\'' +
                 ", spwd=" + spwd +
                 '}';
     }
 }

@Autowired

  • 语法:@Autowired(required = "true-默认、false、是否必须进行装配")

  • 修饰:成员变量或对应的构造方法

  • 含义:按照通过set方法进行“类型装配”,set方法可以省略

  • 向spring容器查找IUserService类型的对象实例,并通过构造方法注入给修饰的属性

  • 注意:

    1. 默认是按照类型装配且同set方法

    2. 若容器中有一个类型可以与之匹配则装配成功,若没有一个类型可以匹配则报错NoSuchBeanDefinitionException

    3. 若容器中有多个类型可以与之匹配,则自动切换为按照名称装配,若名称没有对应,则报错NoUniqueBeanDefinitionException

使用方法:

image-20240807001355765

代码实现:

@Autowired(required = false)  
//使用配置将requieed设置为faluse,如果加载不到这个Bean也不会报错      
UserService userService;

3️⃣其他注解

@Primary有两个类型冲突的情况下,此注解修饰的类被列为首选⭐️

     含义:首选项,当类型冲突的情况下,此注解修饰的类被列为首选(备胎扶正)
     修饰:类
     注意:不能单独使用,必须与@Component....联合使用

代码实例:

image-20240806235916251

@Qualifier(value="名称")

含义:按照名称装配      

修饰:成员变量      

注意:不能单独使用,必须与@Autowired联合使用

按照名称装配,配合@AutoWirted联合使用

代码实现:

image-20240807002107267

@Resource(name="名称")

含义:按照名称装配      

修饰:成员变量      

        注意:单独使用

image-20240807002608614

@Scope

含义:配置类的作用域      
修饰:类      
注意:不能单独使用,必须与@Component....联合使用          
@Scope("prototype")          
@Scope("singleton")          
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)         
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)

image-20240807003057797

@PostConstruct

     初始化,修饰方法
     替换:init-method

@PreDestroy

     销毁,修饰方法
     替换:destory-method
spring3.0后是(annotation+JavaConfig配置类)

3.0配置类语法: spring中的新注解

@Configuration

作用:指定当前类是一个配置类 ​ 细节:当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写。

@ComponentScan

作用:用于通过注解指定spring在创建容器时要扫描的包 ​ 属性:value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。 ​ 替换:<context:component-scan base-package="com.apesource">/context:component-scan

@PropertySource

作用:用于指定properties文件的位置 ​ 属性:value:指定文件的名称和路径。 ​ 配合@Value使用 ​ 替换:<context:property-placeholder location="classpath:message.properties">/context:property-placeholder

@Import

作用:用于导入其他的配置类 ​ 属性:value:用于指定其他配置类的字节码。 ​ 例子:@Import(SystemSpringConfig.class)

@Bean

作用:用于把当前方法的返回值作为bean对象存入spring的容器中 ​ 属性:name:用于指定bean的id。当不写时,默认值是当前方法的名称

可注入系统类,也可注入程序员自己写的类

dbUtil-阿帕奇提供操作数据库的插件

核心类:QueryRunner .query() 查询 .update() 增删改

lombok插件 功能:对实体类自动,动态生成getset,无参有参..... 步骤: 1.idea安装插件(只做一次) 2.添加坐标 3.编写注解

junit测试 使用步骤:

1.坐标 2.注解(修饰方法)

@Test======>可以运行的方法

@Before====>@Test运行之前

@After=====>@Test运行之后

xml实现

代码步骤:

1. 编写实体类,用注解替代有参,无参,构造方法

@dao包含了有参、无参、构造

2. 编写dao层接口方法,并实现;service层set注入dao层,并实现;controller层set注入service层,并实现

3. 编写资源文件,关于数据库的连接信息

4. 编写配置文件,将bean放在ioc容器中

5. 编写测试类

代理模式

什么是代理模式? 代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。 通俗的来讲代理模式就是我们生活中常见的中介。 举个例子来说明:假如说我现在想买一辆二手车,虽然我可以自己去找车源, 做质量检测等一系列的车辆过户流程,但是这确实太浪费我得时间和精力了。 我只是想买一辆车而已为什么我还要额外做这么多事呢?于是我就通过中介 公司来买车,他们来给我找车源,帮我办理车辆过户流程,我只是负责选择 自己喜欢的车,然后付钱就可以了。

为什么要用代理模式? 中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象, 而代理类对象可以在客户类和委托对象之间起到中介的作用,其 特征是代理类和委托类实现相同的接口。 开闭原则,增加功能: 代理类除了是客户类和委托类的中介之外,我们还可以通过给代理 类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代 理类而不需要再修改委托类,符合代码设计的开闭原则。

有哪几种代理模式? 我们有多种不同的方式来实现代理。如果按照代理创建的时期来进行分类的话 可以分为两种: 静态代理: 静态代理是由程序员创建或特定工具自动生成源代码,在对其编译。 在程序员运行之前,代理类.class文件就已经被创建了。

基于接口的动态代理(jdk自带)               
基于子类的动态代理(第三方)               
        静态代理只能代理一个类,动态代理可依靠反射技术代理多个类

静态代理

动态代理

基于接口的动态代理(jdk自带)

基于子类的动态代理(第三方)

项目示例

项目总结:

1.事务管理应该由service层进行实现 代码优化: ​ 目的:业务层进行事务管理

1.同一个业务方法的多个dao方法公用一个connection对象 ​ 2.ThreadLocal ​ 3.通过连接对象进行事务的统一管理

第一版

安全进行转账,采用事务管理的方式

代码步骤

  1. 创建事务管理工具类

    • 1.1 注入连接工具类

    • 1.2 开启事务

    • 1.3 提交事务

    • 1.4 回滚事务

    • 1.5 关闭事务

  1. 创建连接工具类

    • 2.1 装配数据源

    • 2.2 获取线程区域对象

    • 2.3 获取连接

    • 2.4 移除连接

3. 编写实体类

4. controller层、service层、dao层接口方法一致,编写相关实现类

5. 编写数据库资源文件

6. 编写spring配置文件

7. 编写测试类

完成安全转账功能,若中途出现错误,事务则会回滚,转账钱数不会出错。

第二版

考虑到后期业务繁琐,事务管理代码的冗余,故使用代理类解决此项问题,事务管理的代码只用写一遍

代码步骤:

1. 编写代理类

2. 删减service实现类中对事务管理类的注入以及相关事务处理的逻辑

3. 修改spring配置文件

  • 19
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值