spring5入门笔记
Spring框架概述
1.Spring是轻量级(体积小,jar包少,可以独立使用)的开源的javaee框架
2.Spring可以解决企业应用开发的复杂性
3.Spring有两个核心部分:IOC,AOP
-
IOC控制反转,把创建对象的过程交给spring
-
AOP面向切面,不修改源代码的情况,添加或者增强功能
4.Spring特点:
(1)方便解耦,简化开发
(2)AOP编程支持
(3)方便程序的测试
(4)方便集成各种其他框架
(5)方便进行事务的操作
(6)降低API的开发难度
入门案例
1.下载Spring
2.创建java工程导入spring相关的jar包
导入
3.创建普通类,创建普通方法
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解析,工程模式,反射
这种原始方式两个类的耦合度太高了,使得如果UserDao改变那么第一个类也会谁之改变
解决方式:
(1)工厂模式
这样通过工厂类 UserFactory降低了两个类的耦合度,但是还是有耦合(工程中不可能做到完全没有耦合),我们继续通过其他方式解耦合,目的使耦合度降到最低就好了
IOC过程(以上面两个类解耦合为例)
(1)在xml文件中写好对应的配置文件
<!-- 配置User对象的创建--> <bean id="user" class="com.ember.spring5.UserDao"></bean>
(2)有service类和dao类,创建工厂类
IOC(接口)
1.ioc思想基于IOC容器完成,IOC容器底层就是对象工厂
2.Spring提供IOC容器实现两种方式(两个接口)
(1)BeanFactory:IOC容器基本实现,是Spring内部的接口,不提供给开发人员使用
加载配置文件的时候不会创建对象,再获取对象或者使用的时候才会创建对象
(2)Application:是BeanFactory接口的子接口,提供了更多更强大的功能,一般是开发人员使用的
在加载配置文件的时候,就会创建配置文件中的对象
3.
使用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配置方式
(3)xml注入其他类型属性
1.字面量
(1)null值:
<!-- 设置空值,不用value属性注入而是用null标签注入--> <property name="address"><null/></property>
(2)属性值包含特殊符号
<!-- 属性值包含特殊符号 1.用转义字符代替特殊字符如<对应<; 2.把带特殊符号的内容写道CDATA里 --> <property name="address" value="<<南京<<"></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
2.使用util标签完成list集合注入提取
工厂bean
spring有两种bean,第一种就是我们上面学的普通bean(在配置文件中定义bean的类型就是返回类型)
第二种就是工厂bean(在配置文件中定义的类型可以和返回类型不一样)
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是单实例对象(即多个对象对应的地址是同一个地址)
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>
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包
<!--直接配置连接池--> <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&serverTimezone=UTC"></property> <property name="username" value="root"></property> <property name="password" value="20001103"></property> </bean>
2.通过引入外部的属性文件配置数据库连接池
这个在jdbc中就使用过
(1)
(02)把外部的properties属性文件引入到spring配置文件中
引入context名称空间
<?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&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包
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!