spring学习笔记
spring核心部分:IOC AOP
IOC: (Inversion of Control,IOC)控制反转,把创建对象的过程交给spring进行管理(通常称为Bean),通过配置文件或注解,你可以指定Bean的创建方式、依赖关系等
AOP: (Aspect-Oriented Programming,AOP)面向切面,不修改源代码进行功能增强,通过配置或注解,你可以将切面与目标对象(被通知的对象)关联起来,当目标对象的方法被调用时,Spring会自动应用相应的切面逻辑
spring提供IOC容器实现两种方式:(两个接口)
1)BeanFactory:IOC容器的基本实现,是spring内部使用的接口
1)BeanFactory:IOC容器的基本实现,是spring内部使用的接口
特点:加载配置文件的时候不会创建对象,在获取对象的时候才去创建对象
2)ApplicationContext:BeanFactory的子接口,提供更多更强大的功能,一般由开发人员使用
特点:加载配置文件时就会把再配置文件对象进行创建
ApplicationContext主要实现类
bean管理
1)spring创建对象
2)spring注入属性
bean管理操作实现方式
1)基于xml配置文件方式实现
2) 基于注解方式实现
配置文件:
<bean>标签
id属性:在容器中Bean实例的唯一标识,不允许重复
class属性:要实例化的Bean的全限定名
scope属性 sean的作用范围,常用是Singleton(默认)和prototype
<property>标签:属性注入
name属性:属性名称
value属性:注入的普通属性值
ref属性:注入的对象引用值
<list>标签
<map>标签
<properties>标签
<constructor-arg>标签
IOC操作bean管理
<import>标签:导入其他的Spring的分文件
1)在spring配置文件中,使用bean标签,标签里面添加对应属性
id属性:唯一标识
classs属性:类全路径
name属性:
<!-- <bean class="com.josie.dao.UserDao" name="userDao"></bean>-->
创建对象的时候,默认也是执行无参数构造方法
2)基于xml方式注入属性
DI:依赖注入,就是注入属性
第一种:使用set注入
在spring配置文件中配置对象创建,配置属性注入
第二种:使用有参数的构造进行注入
package com.testdemo;
public class Orders {
private String oname;
private String address;
//有参数构造
public Orders(String oname,String address){
this.oname=oname;
this.address=address;
}
public void orderTest(){
System.out.println(oname+"::"+address);
}
}
import com.testdemo.Orders;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestOrders {
public static void main(String[] args) {
//依赖spring注入,从spring的容器中获取orders
ApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
Orders orders= ioc.getBean("orders", Orders.class);
orders.orderTest();
}
}
<?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">
<!--有参构造注入属性-->
<bean id="orders" class="com.testdemo.Orders">
<constructor-arg name="oname" value="abc"/>
<constructor-arg name="address" value="China"/>
</bean>
</beans>
xml注入其他类型属性
字面量(赋了固定值的变量)
1)null值
<property name="address"> <null/></property>
2)属性值包含特殊符号
<!--属性值包含特殊符号--><property name="address"> <value><![CDATA[<<南京>>]]></value></property>
运行输出 <<南京>>
注入属性-外部bean
1)创建service类和dao类
package com.josie.dao;
public class UserDaoImpl implements UserDao{
@Override
public void update(){
System.out.println("dao update");
}
}
2)在service调用dao里面的方法
package com.josie.service;
import com.josie.dao.UserDao;
import com.josie.dao.UserDaoImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
public class UserService implements IUserService{
//原始方法UserDao userDao = new UserDaoImpl();
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
System.out.println("user service.....");
userDao.update();
}
}
<?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">
<!--services和dao对象的创建-->
<bean id="userService" class="com.josie.service.UserService">
<!--注入userDao对象
name属性值:类里面属性名称
ref属性:创建userDao对象bean标签id值
-->
<property name="userDao" ref="userDaoImpl"></property>
</bean>
<bean id="userDaoImpl" class="com.josie.dao.UserDaoImpl"></bean>
</beans>
注入属性-内部bean和级联赋值
1)一对多的关系:部门和员工
一个部门有多个员工,一个员工属于一个部门,部门是一,员工是多
2)在实体类之间表示一对多关系,员工所属部门用对象类型属性进行表示
3)在spring配置文件中进行配置
package com.bean;
public class Emp {
private String ename;
public String gender;
//员工属于某一个部门,使用对象形式表示
private Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setEname(String ename) {
this.ename = ename;
}
public void add(){
System.out.println(ename+"::"+gender+"::"+dept);
}
}
package com.bean;
public class Dept {
private String dname;
public void setDname(String dname) {
this.dname = dname;
}
@Override
public String toString() {
return "Dept{" +
"dname='" + dname + '\'' +
'}';
}
}
<?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">
<!--内部bean-->
<bean id="emp" class="com.bean.Emp">
<!--设置2个普通属性-->
<property name="ename" value="lucky"></property>
<property name="gender" value="女"></property>
<!--设置对象类型属性-->
<property name="dept">
<bean id="dept" class="com.bean.Dept">
<property name="dname" value="安保部"></property>
</bean>
</property>
</bean>
</beans>
级联赋值
<?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">
<!--级联赋值-->
<bean id="emp" class="com.bean.Emp">
<!--设置2个普通属性-->
<property name="ename" value="lucky"></property>
<property name="gender" value="女"></property>
<!--级联赋值-->
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.bean.Dept">
<property name="dname" value="财务部"></property>
</bean>
</beans>
xml注入集合属性
1)注入数组类型属性
2)注入list集合类型属性
3)注入map集合类型属性
创建类,定义属性
package com.demo1;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Stu {
//数组类型的属性
private String[] courses;
//list集合类型属性
private List<String> list;
//map类型属性
private Map<String,String> maps;
//set集合类型属性
private Set<String> sets;
public String[] getCourses() {
return courses;
}
public List<String> getList() {
return list;
}
public Map<String, String> getMaps() {
return maps;
}
public void setSets(Set<String> sets) {
this.sets = sets;
}
}
在spring配置文件中进行配置
<?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">
<!--集合类型属性的注入-->
<bean id="stu" class="com.demo1.Stu">
<!--数组类型属性的注入-->
<property name="courses">
<array>
<value>java课程</value>
<value>Python课程</value>
</array>
</property>
<!--list类型属性的注入-->
<property name="list">
<list>
<value>张三</value>
<value>小三</value>
</list>
</property>
<!--map类型属性的注入-->
<property name="map">
<map>
<entry key="Java" value="java"></entry>
<entry key="Python" value="python"></entry>
</map>
</property>
<!--set类型属性的注入-->
<property name="sets">
<set>
<value>MySQL</value>
<value>Redis</value>
</set>
</property>
</bean>
</beans>
test方法
package com.testDemo1;
import com.demo1.Stu;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Testdemo1 {
@Test
public void testCollection(){
ApplicationContext context = new
ClassPathXmlApplicationContext("bean.xml");
Stu stu = context.getBean("stu", Stu.class);
stu.test();
}
}
在集合里面设置对象类型属性
package com.demo1;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Stu {
public void setCourses(String[] courses) {
this.courses = courses;
}
//数组类型的属性
private String[] courses;
public void setList(List<String> list) {
this.list = list;
}
public void setMaps(Map<String, String> maps) {
this.maps = maps;
}
public void setSets(Set<String> sets) {
this.sets = sets;
}
//list集合类型属性
private List<String> list;
//map类型属性
private Map<String,String> maps;
//set集合类型属性
private Set<String> sets;
public void setCourseList(List<Course> courseList) {
this.courseList = courseList;
}
//学生所学的多门课程
private List<Course> courseList;
public void test(){
System.out.println(Arrays.toString(courses));
System.out.println(list);
System.out.println(maps);
System.out.println(sets);
}
}
package com.demo1;
public class Course {
@Override
public String toString() {
return "Course{" +
"cname='" + cname + '\'' +
'}';
}
public void setCname(String cname) {
this.cname = cname;
}
private String cname;
}
<?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">
<!--集合类型属性的注入-->
<bean id="stu" class="com.demo1.Stu">
<!--数组类型属性的注入-->
<property name="courses">
<array>
<value>java课程</value>
<value>Python课程</value>
</array>
</property>
<!--list类型属性的注入-->
<property name="list">
<list>
<value>张三</value>
<value>小三</value>
</list>
</property>
<!--map类型属性的注入-->
<property name="maps">
<map>
<entry key="Java" value="java"></entry>
<entry key="Python" value="python"></entry>
</map>
</property>
<!--set类型属性的注入-->
<property name="sets">
<set>
<value>MySQL</value>
<value>Redis</value>
</set>
</property>
<!--注入list集合类型,值是对象类型-->
<property name="courseList">
<list>
<ref bean="course1"></ref>
<ref bean="course2"></ref>
</list>
</property>
</bean>
<!--创建多个对象属性值-->
<bean id="course1" class="com.demo1.Course">
<property name="cname" value="Spring框架"></property>
</bean>
<bean id="course2" class="com.demo1.Course">
<property name="cname" value="MyBetis框架"></property>
</bean>
</beans>
把集合注入部门提取出来
在spring配置文件中引入名称空间util
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/beans/spring-util.xsd">
<!--集合类型属性的注入-->
</beans>
使用util标签完成list集合注入提取
<!--提取list集合类型属性的注入-->
<util:list id="bookList">
<value>易筋经</value>
<value>西游记</value>
</util:list>
<!--提取list集合类型属性注入使用-->
<bean id="book" class="com.demo1.Book">
<property name="list" ref="bookList"></property>
</bean>
package com.demo1;
import java.util.List;
public class Book {
private List<String> list;
public void setList(List<String> list) {
this.list = list;
}
public void test(){
System.out.println(list);
}
}
IOC操作Bean管理(FactoryBean)
1.spring有两种bean,一种普通bean,一种工厂bean(FactoryBean)
2.普通bean:在配置文件中定义的bean类型就是返回的类型
3.工厂bean,在配置文件中定义的bean类型可以和返回的类型不一样
1)创建类,让这个类作为工厂bean,实现接口factory bean
2)实现接口里面的方法,在实现的方法中定义返回的bean类型
package com.factorybean;
import com.demo1.Course;
import org.springframework.beans.factory.FactoryBean;
public class MyBean implements FactoryBean<Course> {
@Override
public Course getObject() throws Exception {
//定义返回bean
Course course = new Course();
course.setCname("josie");
return course;
}
@Override
public Class<?> getObjectType() {
return null;
}
}
@Test
public void test3(){
ApplicationContext context = new
ClassPathXmlApplicationContext("bean3.xml");
Course course = context.getBean("myBean", Course.class);
System.out.println(course);
}
}
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<!--提取list集合类型属性注入使用-->
<bean id="myBean" class="com.factorybean.MyBean">
</bean>
</beans>
配置文件中定义的类型是MyBean,返回的是Course类型
IOC操作Bean管理(bean作用域)
1、在spring里面,设置创建bean实例是单实例还是多实例
2、在spring里面,在默认情况下bean是一个单实例对象
输出的地址一样,说明是单实例
3、如何设置单实例还是多实例
1)在spring配置文件bean标签里面有属性scope用于设置单实例还是多实例
2)scope属性值
a.默认值,singleton,表示是单实例对象
b.prototype, 表示是多实例对象
3)singleton和prototype区别
a.设置scope值是singleton时候,加载spring配置文件时候就会创建单实例对象
b.设置scope值是prototype时候,不是加载spring配置文件时候创建对象,在调用getBean方法时候创建多实例对象
IOC操作bean管理(生命周期)
package com.bean;
public class Orders {
//无参构造
public Orders(){
System.out.println("第一步,执行无参数构造创建bean实例");
}
public void setOname(String oname) {
this.oname = oname;
System.out.println("第二步,调用set方法设置值");
}
private String oname;
//创建执行的初始化方法
public void initMethod(){
System.out.println("第三步,执行初始化方法");
}
//创建执行销毁的方法
public void destroyMethod(){
System.out.println("第五步,执行销毁方法");
}
}
package com.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.lang.Nullable;
public class MyBeanPost implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化之前执行的方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化之后执行的方法");
return bean;
}
}
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<!--提取list集合类型属性注入使用-->
<bean id="orders" class="com.bean.Orders" init-method="initMethod" destroy-method="destroyMethod">
<property name="oname" value="手机"></property>
</bean>
<!--配置后置处理器-->
<bean id="myBeanPost" class="com.bean.MyBeanPost"></bean>
</beans>

