Spring5----复习笔记1
今天学完了Spring5,还是感觉迷迷糊糊的,对其中的一些操作记忆还不是很劳,今天开始复习Spring5,巩固一下记忆。
首先在学完了Spring5之后,这个框架给我的感觉就是创建对象更加方便了,我们可以通过注解或者配置文件的方式进行对象的注入,不用再自己手动创建了。
其中还有JDBC的新操作以及事务管理,大大简化了我们的代码,让我们的代码更加清新。
首先Spring5运用了IOC(控制反转)编程思想(也叫依赖注入),那么什么是IOC编程思想呢?
我们都知道在面向对象的软件设计中,它的底层都是由N个对象构成,各个对象之间通过相互合作,最终实现系统地业务逻辑。
但是在庞大的软件体系中对象的依赖关系越来越复杂,耦合度越来越高,很有可能“牵一发而动全身”,因此,Michael Mattson提出了IOC理论。
IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦。
我们再来看看,控制反转(IOC)到底为什么要起这么个名字?我们来对比一下:
软件系统在没有引入IOC容器之前,如图1所示,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在自己手上。
软件系统在引入IOC容器之后,这种情形就完全改变了,如图3所示,由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。
通过前后的对比,我们不难看出来:对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。
IOC这个东西好像就是可以利用配置文件进行对象的创建,那么如何用代码实现呢?
使用我们要引入Spring的jar包,可以用Maven,也可以去官网下载:
需要使用的jar包
接着就可以使用IOC进行bean管理操作了,bean管理:
(1) Spring创建对象
(2) Spring注入属性
我们可以在配置文件中进行对象的创建以及向这个对象中注入属性。
1、基于XML创建对象
我们首先创建User(Bean)类:
public class User { private String username; public void add() { System.out.println("add........."); } }
接着就可以在xml文件中利用bean标签创建对象了,
在idea的src下创建Spring.xml文件后:
<!--配置User对象创建-->
<bean id="user" class="com.spring5.User"></bean>
对象就创建在IOC容器中了,这感觉好像有点虚幻,我们可以测试一下。
在java程序中:
@Test public void testUser(){ //1.加载spring的配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); //2.获取配置创建的对象 User user = context.getBean("user", User.class); user.add(); System.out.println(user); }
运行后控制台输出:
add.........
com.spring5.User@16f7c8c1
这说明我们的对象确实创建出来了。
2、基于xml注入基本属性
DI:依赖注入,注入属性 第一种注入方式 : set方法注入 (1) 创建一个类,定义属性的对应的set方法 见spring5中的 Book类 (2) 在spring配置文件中配置对象的创建,再配置属性的注入 bean内使用property完成属性注入 name:属性名称 value:属性注入的值 第二种注入方式 : 构造函数注入 (1) 创建一个类,定义属性和有参构造 见spring5中的 Orders类 (2) 在spring配置文件中配置对象的创建,以及构造器参数的导入 bean内使用 constructor-arg 完成属性注入 name:属性名称 value:属性注入的值
Bean类:
public class Book { //创建属性 private String bname; private String bauthor; private String address; //set方法注入 public void setBname(String bname) { this.bname = bname; } public void setAddress(String address) { this.address = address; } public void setBauthor(String bauthor) { this.bauthor = bauthor; } @Override public String toString() { return "Book{" + "bname='" + bname + '\'' + ", bauthor='" + bauthor + '\'' + ", address='" + address + '\'' + '}'; } }
xml配置文件(基于set方法):
<!--创建对象--> <bean id="book" class="com.spring5.Book"> <!--bean内使用property完成属性注入 name:属性名称 value:属性注入的值 --> <property name="bname" value="易筋经"> </property> <property name="bauthor" value="达摩老祖"> </property> <!--null值--> <!-- <property name="address">--> <!-- <null/>--> <!-- </property>--> <!--属性值中包含特殊符号 1、<>进行转义 << >> 2、把带特殊符号内容写到CDATA中 --> <property name="address"> <value><![CDATA[<<南京>>]]></value> </property> </bean>
java程序:
@Test public void testBook1() { //1.加载spring的配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); //2.获取配置创建的对象 Book book = context.getBean("book", Book.class); System.out.println(book); }
控制台输出:
Book{bname='易筋经', bauthor='达摩老祖', address='<<南京>>'}
我们可以看到属性确实被注入进对象了。
xml配置文件(基于构造器):
Order(Bean)类:
public class Orders { private String oname; private String address; public Orders(String oname, String address) { this.oname = oname; this.address = address; } @Override public String toString() { return "Orders{" + "oname='" + oname + '\'' + ", address='" + address + '\'' + '}'; } }
注意这里没有空构造器,所以当我们在xml文件中直接创建对象(空)时会报错
xml配置文件(构造器):
<bean id="order" class="com.spring5.Orders"> <constructor-arg name="oname" value="computer"> </constructor-arg> <constructor-arg name="address" value="cn"> </constructor-arg> </bean>
java程序:
@Test
public void testOrder1()
{
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Orders order = context.getBean("order", Orders.class);
System.out.println(order);
}
控制台输出:
Orders{oname='computer', address='cn'}
简化:我们可以在xml配置文件中通过p命名空间简化set注入属性操作(不过这个操作我倒是不经常用,property其实是我最喜欢用的方式):
首先在beans标签中添加xmlns:p属性:
xmlns:p="http://www.springframework.org/schema/p"
接着配置bean对象:
<!--创建对象--> <bean id="book1" class="com.spring5.Book" p:bname="九阳神功" p:bauthor="无名氏"> <!--bean内使用property完成属性注入 name:属性名称 value:属性注入的值 --> </bean>
java程序:
@Test public void testBook2() { //1.加载spring的配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); //2.获取配置创建的对象 Book book = context.getBean("book1", Book.class); System.out.println(book); }
控制台输出:
Book{bname='九阳神功', bauthor='无名氏', address='null'}
3、基于xml注入外部bean属性
UserDao接口以及UserDaoImpl类以及UserService类:
public interface UserDao { public void update(); }
public class UserDaoImpl implements UserDao { @Override public void update() { System.out.println("Dao update......"); } }
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(); } }
xml配置:
<!--Service和Dao对象创建--> <bean id="userService" class="com.service.UserService"> <!--注入userDao对象 ref属性:创建userDao对象bean标签id值 --> <property name="userDao" ref="userDao"> </property> </bean> <bean id="userDao" class="com.dao.UserDaoImpl"> </bean>
我们在property标签中添加ref属性,属性值是外部bean对象的id
java程序:
@Test public void testUserService(){ ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml"); UserService userService = context.getBean("userService", UserService.class); userService.add(); }
控制台输出:
service add......
Dao update......
4、基于xml设置内部Bean属性:
Employee类以及Department类(Bean):
public class Department { private String dname; public void setDname(String dname) { this.dname = dname; } @Override public String toString() { return "Department{" + "dname='" + dname + '\'' + '}'; } }
public class Employee { private String ename; private String gender; //员工所属的部门 private Department department; public void setDepartment(Department department) { this.department = department; } public void setEname(String ename) { this.ename = ename; } public void setGender(String gender) { this.gender = gender; } public Department getDepartment() { return department; } @Override public String toString() { return "Employee{" + "ename='" + ename + '\'' + ", gender='" + gender + '\'' + ", department=" + department + '}'; } }
web.xml配置:
<!--内部bean--> <bean id="emp" class="com.bean.Employee"> <property name="ename" value="张三"> </property> <property name="gender" value="男"> </property> <!--设置对象类型属性--> <property name="department"> <bean id="dept" class="com.bean.Department"> <property name="dname" value="程序猿"> </property> </bean> </property> </bean>
我们可以看到就是往property中添加对象
java程序:
@Test public void testEmp(){ ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml"); Employee emp = context.getBean("emp", Employee.class); System.out.println(emp); }
控制台输出:
Employee{ename='张三', gender='男', department=Department{dname='程序猿'}}
我们也可以通过级联赋值方式配置:
xml配置文件内容:
<!--级联赋值--> <bean id="emp" class="com.bean.Employee"> <property name="ename" value="张三"> </property> <property name="gender" value="男"> </property> <!--级联赋值--> <property name="department" ref="dept"> </property> <!--需要在Employee类中实现dept的get方法--> <property name="department.dname" value="技术部"> </property> </bean> <bean id="dept" class="com.bean.Department"> <property name="dname" value="财务部"> </property> </bean>
我们首先利用外部bean创建对象,再利用级联赋值修改内部对象的属性值。
通过使用property属性,name是类中对象名称.属性名称,这要求均实现set方法。
最终输出:
Employee{ename='张三', gender='男', department=Department{dname='技术部'}}