Spring框架学习笔记一
Spring框架概述
- Spring是轻量级的开源的JavaEE框架
- Spring可以解决企业应用开发的复杂性
- Spring有两个核心部分:IOC和Aop
- IOC:控制反转,把创建对象过程交给Spring进行管理
- Aop:面向切面,不修改源代码进行功能增强
- Spring特点;
- 方便解藕,简化开发
- Aop编程支持
- 方便程序的测试
- 方便集成各种框架
- 方便进行事务操作
- 降低API开发难度
下载地址
https://repo.spring.io/release/org/springframework/spring/
官网:https://spring.io/projects/spring-framework#overview
GA是稳定版本
简单例子
-
创建普通类,普通方法
创建Java文件 User.java
public class User{ public void add(){ System.out.println("add..."); } } -
利用xml配置User对象创建
创建xml文件 bean1.xml
<bean id="user" class="spring5.User"></bean> //class是User对象的路径 -
进行测试代码编写
建测试类 testSpring.java
@Test public void testAdd(){ //1.加载spring配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); //括号里面是xml文件的路径和名称,在同一个src下面用ClassPath //2.获取配置创建的对象 User user = context.getBean("user", User.class); //第一个值是xml文件里对象的id,第二个是普通对象的类 System.out.println(user);//输出类的地址 user.add(); }
IOC容器
什么是IOC
- 控制反转,把对象创建和对象之间的调用过程交给Spring进行管理
- 使用IOC的目的:为了耦合度降低
- 上面的入门案例就是IOC的实现
IOC底层原理
- xml解析+工厂模式+反射
代码实现
- 原始方式
class UserDao{
add(){
...
}
}
class UserService{
execute(){
UserDao dao = new UserDao();
dao.add();
}
}
//耦合度过高
- 工厂模式
class UserDao{
add(){
...
}
}
class UserFactory{
public static UserDao getDao(){
return new UserDao();//返回一个UserDao实例
}
}
class UserService{
execute(){
UserDao dao = UserFactory.getDao();//直接取UserFactory里的对象
dao.add();
}
}
//降低了Dao和Service之间的耦合度
- IOC过程
第一步:xml配置文件,配置创建的对象
<bean id="dao" class="com.spring.UserDao"></bean>
第二步:有service类和dao类,创建工厂类
class UserFactory{
public static UserDao getDao(){
String classValue = class属性值;//1.xml解析,即得到com.spring.UserDao
//2.通过反射创建对象。反射:得到类的字节码文件
Class clazz = Class.forName(classValue);
//3.最后创建对象并return
return (UserDao)clazz.newInstance();
}
}
//进一步降低耦合度
IOC(接口)
-
IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
-
Spring提供IOC容器实现的两种方式(两个重要接口)
-
BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供给开发人员进行使用
-
ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般面向开发人员进行使用
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
两个接口作用相似,不同点:
BeanFactory:加载配置文件时不会创建对象,获取或使用对象的时候才去创建对象
ApplicationContext:加载配置文件的时候,就会把配置文件里的对象进行创建
-
-
ApplicationContext接口的实现类(IDEA里面command+h可以看到)
-
FileSystemXmlApplicationContext
系统里面的整体路径
-
ClassPathXmlApplicationContext
src下面的路径
-
IOC操作Bean管理
什么是Bean管理(两个操作)
- Spring创建对象
- Spring注入属性
Bean管理操作有两种实现方式
-
基于注解方式实现
-
基于xml配置文件方式实现
-
基于xml创建对象
- 在Spring配置文件中使用bean标签,添加对应属性
<bean id="dao" class="com.spring.UserDao"></bean>- bean标签常用属性:
id:唯一标识,通过id可以得到这个对象
class:类全路径(包类路径)
name:和id一样,id中不能加特殊符号,name可以(不常用)
- 创建对象的时候,默认也是执行无参数构造方法
-
基于xml注入属性
- DI:依赖注入,就是注入属性,是IOC的一种具体实现
-
第一种注入方式:set方法
public class Book{ private String bname; public void setBname(String bname){ this.bname = bname;//使用command+n自动生成 } public static void main(String[] args){ Book book = new Book(); book.setBname("abc"); } }使用set方法进行注入属性
//1.创建类,定义属性和对应的set方法 public class Book{ private String bname; private String bauthor; public void setBname(String bname){ this.bname = bname;//使用command+n自动生成 } public void setBauthor(String bauthor){ this.bauthor = bauthor;//使用command+n自动生成 } } //2.在Spring配置文件(xml)配置对象创建,配置属性注入 <bean id="book" class="com.spring.Book"> //创建对象 <!--使用property完成属性注入 name:类里面的属性名称 value:向属性里注入的值 --> <property name="bname" value="一只特立独行的猪"></property> //注入属性 <property name="bauthor" value="王小波"></property> </bean> -
第二种注入方式:有参构造方式
public class Book{ private String bname; public Book(String bname){ this.bname = bname; } public static void main(String[] args){ Book book = new Book("abc"); } }使用有参构造进行属性注入
//1.创建类,定义属性和有参构造 public class Orders{ private String oname; private String address; public Orders(String oname, String address){ this.oname = oname; this.address = address; } } //2.在Spring配置文件(xml)配置对象创建,配置属性注入 <bean id="orders" class="com.spring.Orders"> //创建对象 //如果只写<bean>的这一句(⬆️一行)那么就会找Orders里面的无参构造,但是找不到,因为已经有有参构造了,所以需要注入属性 <constructor-arg name="oname" value="chabaidao"></constructor-arg> <constructor-arg name="address" value="BUPT"></constructor-arg> //另一个写法:index=0表示有参构造的第一个属性,用name更准确 <constructor-arg index="0" value="chabaidao"></constructor-arg> </bean> -
xml注入其他类型属性
-
字面量
-
null值
<property name="address"> <null/> </property> -
属性值包含特殊符号 eg:<<南京>>
第一种方式:转义 > ;代表> < ;代表<
第二种方式:把带特殊符号内容写到CDATA
<property name="address"> <value><![CDATA[<<南京>>]]></value> </property>
-
-
-
基于xml注入属性-外部bean
-
创建两个类service类和dao类
-
在service调用dao里面的方法
-
在spring配置文件中进行配置
//原始方法: //dao接口 public interface UserDao{ public void update(); } //dao实现 public class UserDaoImpl implements UserDao{ public void update(){ System.out.println("dao update..."); } } //service public class UserService{ public void add(){ //创建UserDao对象原始方法 //UserDao userDao = new UserDaoImpl(); //userDao.update(); } }//UserDao public interface UserDao{ public void update(); } //dao实现 public class UserDaoImpl implements UserDao{ public void update(){ System.out.println("dao update..."); } } //UserService public class UserService{ //创建UserDao类型属性,生成set方法 private UserDao userDao; public void setUserDao(UserDao userDao){ this.userDao = userDao; } } //配置文件 <bean id="userService" class="com.spring.service.UserService"> <property name="userDao" ref="userDaoIm"></property> //name是属性名称,即Service类里面起的名字 //因为是dao对象所以是ref,ref的值是下面实现类bean的id //在外面写所以是外部bean </bean> //路径是实现类的路径 <bean id="userDaoIm" class="com.spring.dao.UserDaoImpl"></bean>
基于xml注入属性-内部bean
-
一对多关系:eg 部门和员工
-
在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示
//部门类 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; } } -
在Spring配置文件进行配置
<bean id="emp" class="com.spring.Emp"> //两个普通属性 <property name="ename" value="Lucy"></property> <property name="gender" value="女"></property> //一个对象类型属性 <property name="dept"> //内部bean <bean id="dept" class="com.spring.Dept"> <property name="dname" value="IT"></property> </bean> </property> </bean>
基于xml注入属性-级联赋值
第一种
<bean id="emp" class="com.spring.Emp">
//两个普通属性
<property name="ename" value="Lucy"></property>
<property name="gender" value="女"></property>
//一个对象类型属性 级联赋值
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.spring.Dept">
<property name="dname" value="IT"></property>
</bean>
第二种
//先在Emp类里生成dept的get方法
public Dept getDpet(){
return dept;
}
//配置文件
<bean id="emp" class="com.spring.Emp">
//两个普通属性
<property name="ename" value="Lucy"></property>
<property name="gender" value="女"></property>
//一个对象类型属性 级联赋值
<property name="dept" ref="dept"></property>
<property name="dept.dname" value="研发部"></property>
</bean>
基于xml注入集合类型的属性
- 注入数组类型属性
- 注入List集合类型属性
- 注入Map集合类型属性

浙公网安备 33010602011771号