spring5入门笔记

Spring框架概述

1.Spring是轻量级(体积小,jar包少,可以独立使用)的开源的javaee框架

2.Spring可以解决企业应用开发的复杂性

3.Spring有两个核心部分:IOC,AOP

  1. IOC控制反转,把创建对象的过程交给spring

  2. AOP面向切面,不修改源代码的情况,添加或者增强功能

4.Spring特点:

(1)方便解耦,简化开发

(2)AOP编程支持

(3)方便程序的测试

(4)方便集成各种其他框架

(5)方便进行事务的操作

(6)降低API的开发难度

入门案例

1.下载Spring

网址repo.spring.io

2.创建java工程导入spring相关的jar包

image-20220320202844343

导入

image-20220320203314055

3.创建普通类,创建普通方法

image-20220320203625594

4.创建spring的配置文件,在配置文件中配置你要创建的对象

(1)spring的配置文件是xml格式的(和mybatis一样)

<?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">
<!-- 配置User对象的创建-->
<bean id="user" class="com.ember.spring5.User"></bean>
这个class是对应类的绝对路径,id是唯一标识到时候导入配置文件用的
</beans>

5.进行测试代码编写

package com.ember.spring5;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring5 {
@Test
public void testAdd() {
// 1.加载spring的配置文件
Object object;
ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
// 2.获取配置创建的对象
User user= context.getBean("user",User.class);
System.out.println(user);
user.add();
}
}

运行成功这就说明spring环境成功

IOC容器

概念和原理

(1)控制反转,把对象创建和对象之间的调用过程交给spring管理

(2)使用IOC目的:降低耦合度

(3)入门案例就是ioc的实现

底层原理

(1)xml解析,工程模式,反射

image-20220322160701278

这种原始方式两个类的耦合度太高了,使得如果UserDao改变那么第一个类也会谁之改变

解决方式:

(1)工厂模式

image-20220322161218840

这样通过工厂类 UserFactory降低了两个类的耦合度,但是还是有耦合(工程中不可能做到完全没有耦合),我们继续通过其他方式解耦合,目的使耦合度降到最低就好了

IOC过程(以上面两个类解耦合为例)

(1)在xml文件中写好对应的配置文件

<!-- 配置User对象的创建-->
<bean id="user" class="com.ember.spring5.UserDao"></bean>

(2)有service类和dao类,创建工厂类

image-20220322162511042

IOC(接口)

1.ioc思想基于IOC容器完成,IOC容器底层就是对象工厂

2.Spring提供IOC容器实现两种方式(两个接口)

(1)BeanFactory:IOC容器基本实现,是Spring内部的接口,不提供给开发人员使用

加载配置文件的时候不会创建对象,再获取对象或者使用的时候才会创建对象

(2)Application:是BeanFactory接口的子接口,提供了更多更强大的功能,一般是开发人员使用的

在加载配置文件的时候,就会创建配置文件中的对象

3.image-20220322181948205

使用class..则需要传入xml相对于src对应的路径。使用file。。。则需要使用根盘对应的路径

IOC具体操作

Bean管理

指的是两个操作:

(1)Spring创建对象

(2)Spring注入属性

实现方式:

(1)基于xml配置文件方式实现

(2)基于注解方式实现

基于xml实现:

(1)创建对象:

在配置文件中使用bean标签,标签里面添加对应属性,实现对象的创建

<bean id="user" class="com.ember.spring5.User"></bean>

bean标签常用属性:

id(唯一标识),class(要创建对象所属类的路径),name(可以加特殊符号的唯一标识,基本不用)

(注意:创建对象的时候,默认也是执行无参的构造方法进行创建,如果没有无参的构造方法则会报错)

(2)注入属性:

(1)DI:依赖注入,就是注入属性(要在创建对象的基础之上完成)

1.set方法注入(创建属性以及对应的set方法才行)

public class Book {
private String bname;
public void setBname(String bname) {
this.bname = bname;
}
public static void main(String[] args) {
Book book=new Book();
book.setBname("Spring");
}
}

在spring配置文件中配置对象创建,配置属性注入

<!-- 使用set方法注入-->
<bean id="book" class="com.ember.spring5.Book">
<!-- 使用property完成属性注入
name:表示类里面的属性名称(要与set方法里参数的名称一致)
value:表示要注入的值
-->
<property name="bname" value="Spring"></property>
</bean>

随后我们在test类中引入配置文件并运行

@Test
public void testBook1() {
// 1.加载spring的配置文件
Object object;
ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
// 2.获取配置创建的对象
Book book= context.getBean("book",Book.class);
book.testDemo();
}

2.有参构造注入(要创建属性和对应有参构造函数)

public class Book {
private String bname;
public Book(String string){
this.bname=string;
}
public static void main(String[] args) {
Book book=new Book("Spring");
}
}

在spring配置文件中通过这种方式注入

首先要创建类,创建好属性以及有参构造

public class Orders {
private String oname;
private String address;
public Orders(){}
public Orders(String oname,String address){
this.address=address;
this.oname=oname;
}
public void testDemo(){
System.out.println(oname+"::"+address);
}
}

接着写配置文件注入

<!-- 有参的构造注入属性-->
<bean id="orders" class="com.ember.spring5.Orders">
<!-- constructor-arg标签 和 property标签的属性意义是一样的 -->
<constructor-arg name="oname" value="Spring"></constructor-arg>
<constructor-arg name="address" value="China"></constructor-arg>
</bean>

接着写测试类运行

@Test
public void testOrders1() {
// 1.加载spring的配置文件
Object object;
ApplicationContext context=new ClassPathXmlApplicationContext("bean1.xml");
// 2.获取配置创建的对象
Orders orders=context.getBean("orders",Orders.class);
orders.testDemo();
}
补充:p名称空间注入(不常用)

(1)使用p名称空间注入,可以简化基于xml配置方式

image-20220322192613299

image-20220322192717992

(3)xml注入其他类型属性

1.字面量

(1)null值:

<!-- 设置空值,不用value属性注入而是用null标签注入-->
<property name="address"><null/></property>

(2)属性值包含特殊符号

<!-- 属性值包含特殊符号
1.用转义字符代替特殊字符如<对应&lt;
2.把带特殊符号的内容写道CDATA里
-->
<property name="address" value="&lt;&lt;南京&lt;&lt;"></property>
<property name="address">
<value>
<![CDATA[<<南京>>]]>
</value>
</property>
</bean>

注入属性

外部bean:

(1)创建两个类service类和dao类

(2)在service调用dao里的方法

普通的方法是在service类中创建一个dao对象,再调其方法。下面我们在spring中实现

(3)在spring配置文件中进行配置

1.创建service类

public class UserService {
// 创建userdao类型属性,生成set方法
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void add(){
System.out.println("service add......");
userDao.update();
}
}

2.接口dao

public interface UserDao {
public void update();
}

3.接口的实现类

public class UserDaoImpl implements UserDao{
@Override
public void update() {
System.out.println("dao update......");
}
}

4.配置文件完成对象创建与注入

<!--创建service和dao中的对象进行创建-->
<bean id="userService" class="com.ember.spring5.service.UserService">
<!-- 注入userDao对象-->
<!-- ref属性创建userDao对象标签的属性值(id)-->
<property name="userDao" ref="userDaoImpl"></property>
</bean>
<!-- 创建接口类对象是要传入其实现类而不是直接传入接口-->
<bean id="userDaoImpl" class="com.ember.spring5.dao.UserDaoImpl"></bean>

5.测试类

@Test
public void testAdd() {
// 1.加载spring的配置文件
Object object;
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
// 2.获取配置创建的对象
UserService userService = context.getBean("userService", UserService.class);
System.out.println(userService);
userService.add();
}
内部bean和级联赋值

(1)在实体类之间表示一对多关系

一般使用对象类型的属性表示

以下通过配置文件实现

1。先写好两个类中的属性以及set方法

public class Dept {
private String dname;
public void setDname(String dname) {
this.dname = dname;
}
}
public class Emp {
private String ename;
private String gender;
// 使用对象的形式表示员工属于某一个部门
private Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
public void setEname(String ename) {
this.ename = ename;
}
public void setGender(String gender) {
this.gender = gender;
}
}

2.配置文件

<bean id="emp" class="com.ember.spring5.bean.Emp">
<property name="ename" value="小明"></property>
<property name="gender" value="男"></property>
<!-- 对象类型属性注入-->
<property name="dept">
<bean id="dept" class="com.ember.spring5.bean.Dept">
<property name="dname" value="安保部"></property>
</bean>
</property>
</bean>

就是嵌套使用bean

还有一种就是级联对象

<bean id="emp" class="com.ember.spring5.bean.Emp">
<property name="ename" value="小明"></property>
<property name="gender" value="男"></property>
<!-- 级联赋值注入对象属性-->
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.ember.spring5.bean.Dept">
<property name="dname" value="财务部"></property>
</bean>

级联对象的第二种写法(这种写法需要在emp的类文件中写好dept的get方法来获取到对象)

<bean id="emp" class="com.ember.spring5.bean.Emp">
<property name="ename" value="小明"></property>
<property name="gender" value="男"></property>
<!-- 级联赋值注入对象属性-->
<property name="dept" ref="dept"></property>
<bean id="dept.dname" value="财务部"></bean>
</bean>
注入集合类型属性

1.注入数组类型属性

2.注入List类型属性

3.注入Map类型属性

4.set泪下属性

首先写好属性以及对应的set方法

public class Stu {
// 创建数组类型属性
private String[] courses;
//创建List集合类型的属性
private List<String> list;
// 创建Map类型的属性
private Map<String,String> maps;
// 创建Set集合的属性
private Set<String> set;
public void setSet(Set<String> set) {
this.set = set;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMaps(Map<String, String> maps) {
this.maps = maps;
}
public void setCourses(String[] courses) {
this.courses = courses;
}
}

再去写配置文件注入

<bean id="stu" class="com.ember.spring5.Array.Stu">
<!-- 数组,可以用array或者list注入-->
<property name="courses">
<array>
<value>java课程</value>
<value>Mysql课程</value>
<value>Javaweb</value>
</array>
</property>
<!-- list集合-->
<property name="list">
<list>
<value>第1</value>
<value>第2</value>
<value>第3</value>
</list>
</property>
<!-- Map类型注入-->
<property name="maps">
<map>
<entry key="JAVA" value="java"></entry>
<entry key="PHP" value="php"></entry>
</map>
</property>
<!-- set集合-->
<property name="set">
<set>
<value>1</value>
<value>2</value>
</set>
</property>
</bean>

测试类

@Test
public void test1() {
// 1.加载spring的配置文件
Object object;
ApplicationContext context=new ClassPathXmlApplicationContext("beanArray.xml");
// 2.获取配置创建的对象
Stu stu=context.getBean("stu", Stu.class);
stu.test();
}

细节:

(1)在集合中设置对象类型的值

写一个对象类

public class Course {
private String cname;
public void setCname(String cname){
this.cname=cname;
}
}

在目标类中创建好list数组和set方法

private List<Course> courseList;
public void setCourseList(List<Course> courseList) {
this.courseList = courseList;
}
<property name="courseList">
<list>
<ref bean="course1"></ref>
<ref bean="course2"></ref>
</list>
</property>
</bean>
<!-- 创建多个course对象-->
<bean id="course1" class="com.ember.spring5.Array.Course">
<property name="cname" value="sb1"></property>
</bean>
<bean id="course2" class="com.ember.spring5.Array.Course">
<property name="cname" value="sb2"></property>
</bean>

(2)把集合注入部分提取出来

1.在spring配置文件中引入名称空间util

image-20220323180443285

2.使用util标签完成list集合注入提取

image-20220323181448358

工厂bean

spring有两种bean,第一种就是我们上面学的普通bean(在配置文件中定义bean的类型就是返回类型)

第二种就是工厂bean(在配置文件中定义的类型可以和返回类型不一样)

image-20220323182232344

1.class

public class MyBean implements FactoryBean<Course> {
//定义返回bean
@Override
public Course getObject() throws Exception {
Course course=new Course();
return course;
}
//
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
}
<bean id="myBean" class="com.ember.spring5.factorybean.MyBean"></bean>

2.test

@Test
public void test2() {
// 1.加载spring的配置文件
Object object;
ApplicationContext context=new ClassPathXmlApplicationContext("beanArray.xml");
// 2.获取配置创建的对象
Course course=context.getBean("myBean", Course.class);
System.out.println(course);
}

可见配置文件中定义的是

MyBean

而返回的是

Course

bean作用域

就是在Spring里面创建的bean实例分单实例和多实例

在spring里面默认情况下,bean是单实例对象(即多个对象对应的地址是同一个地址)

image-20220326091501603

1.如何设置单实例还是多实例

在spring配置文件bean标签有个属性(scope)用于设置单实例还是多实例

scope属性的值:

默认值:singleton单实例对象

prototype多实例对象

当设置是singleton的时候,在加载配置文件的时候就会自动创建单实例对象

而设置是prototype的时候,是在调用getbean方法的时候才创建多实例对象

request(不常用)

session(不常用)

bean生命周期

生命周期是指从对象创建到对象销毁的过程

(1)通过构造器创建bean实例(无参构造创建)

(2)为bean的属性设置值和其他bean的引用(调用set方法)

(3)调用bean的初始化方法(需要进行配置)

(4)bean可以使用(对象获取到了)

(5)当容器关闭时,调用bean销毁的方法(需要进行配置)

在class文件中设置好要使用的属性,set方法以及初始化,销毁方法

package com.ember.spring5.bean;
public class Orders {
private String oname;
public Orders(){
System.out.println("第一步,执行无参构造创建bean实例");
}
public void setOname(String oname) {
this.oname = oname;
System.out.println("第二步,调用set方法设置属性的值");
}
// 创建执行的初始化的方法
public void initMethod() /*需要在配置文件init-method中配置该方法才会在创建时执行*/
{
System.out.println("第三步,执行初始化的方法");
}
//创建销毁的时候执行的方法
public void destroyMethod(){ /*需要在配置文件中用属性destroy-method配置该方法才能在销毁时执行*/
System.out.println("第四步,执行销毁的方法");
}
}

在配置文件中配置

<bean id="orders" class="com.ember.spring5.bean.Orders" init-method="initMethod" destroy-method="destroyMethod">
<property name="oname" value="手机"></property>
</bean>

设置测试方法

@Test
public void testBean1() {
// 1.加载spring的配置文件
Object object;
ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
// 2.获取配置创建的对象
Orders orders= context.getBean("orders", Orders.class);
System.out.println("第四步,获取到了创建的bean实例对象");
System.out.println(orders);
// 手动让bean实例销毁
((ClassPathXmlApplicationContext)context).close();/* ApplicationContext接口中没有对应的close方法,所以要强转为其子接口后调用close,
或者可以在上面用ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml")来完成实列*/
}
bean的后置处理器

其实在这五步的基础之上还有两步(加上后置处理器后一共有七步)

(1)通过构造器创建bean实例(无参构造创建)

(2)为bean的属性设置值和其他bean的引用(调用set方法)

2.1.把bean的实例传递给bean后置处理器的方法(postProcessBeforeInitialization)

(3)调用bean的初始化方法(需要进行配置)

3.1把bean实例传递给bean后置处理器的方法(postProcessAfterInitialization)

(4)bean可以使用(对象获取到了)

(5)当容器关闭时,调用bean销毁的方法(需要进行配置)

演示添加后置处理器效果

(1)创建类,实现接口(BeanPostProcessor),创建后置处理器

在上面五步的代码基础上添加一个类实现接口,以及配置文件中添加配置

public class MyBeanPost implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化之前bean实例传入的方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化之后执行得方法");
return bean;
}
}

这两个方法到接口中直接复制根据需要改动一下就好了,再到配置文件中添加如下配置

<!-- 配置后置处理器 为当前配置文件中所有的bean都添加了配置处理器-->
<bean id="myBeanPost" class="com.ember.spring5.bean.MyBeanPost">
</bean>

image-20220326103833678

xml自动装配(不常用)

自动装配之前我们在配置文件中设置属性值那是手动装配,而自动装配就是根据指定的装配规则(属性名称胡或者属性类型),Spring自动将匹配的属性值进行注入

2.演示自动装配的过程:

实现自动装配
bean标签属性autowire,配置自动装配
autowire属性常用两个值:byName根据属性名注入(注入值bean的id和类属性名称一样) byType根据属性类型注入
<bean id="emp1" class="com.ember.spring5.autowire.Emp1" autowire="byName">
<!-- <property name="dept1" ref="dept1"></property>-->
</bean>
<bean id="dept1" class="com.ember.spring5.autowire.Dept1"></bean>
</beans>

这里使用了自动根据名称装配则不需要使用property手动装配了

引入外部属性文件

1.直接配置数据库信息

(1)配置德鲁伊连接池

1.引入德鲁伊的jar包

image-20220326114648669

<!--直接配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/sql_store?characterEncoding=utf-8&amp;serverTimezone=UTC"></property>
<property name="username" value="root"></property>
<property name="password" value="20001103"></property>
</bean>

2.通过引入外部的属性文件配置数据库连接池

这个在jdbc中就使用过

(1)

image-20220326120130279

(02)把外部的properties属性文件引入到spring配置文件中

引入context名称空间

image-20220326132053495

image-20220326132106651

<?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">
<!--直接配置连接池-->
<!--<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">-->
<!--<property name="driver" value="com.mysql.jdbc.Driver"></property>-->
<!-- <property name="url" value="jdbc:mysql://localhost:3306/sql_store?characterEncoding=utf-8&amp;serverTimezone=UTC"></property>-->
<!-- <property name="username" value="root"></property>-->
<!-- <property name="password" value="20001103"></property>-->
<!-- </bean>-->
<!-- 引入外部的属性文件-->
<context:property-placeholder location="jb.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driver" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>
</beans>

基于注解实现:

(1)注解是代码的特殊标记,格式:@注解名称(属性名称=属性值,属性名称2=属性值....)

(2)使用注解,注解作用在类,方法,属性上面

(3)使用注解的目的:简化xml的配置

创建对象

Spring针对Bean管理中创建对象提供了几个常用注解

(1)@component

(2)@service

(3)@controller

(4)@Repository

上面的四个注解功能是一样的,都可以用来创建bean的实例

第一步:引入aop依赖jar包

posted @   Ember00  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示