Spirng 是一种轻量级开源的框架。
核心是IOC容器、AOP、JDBCTemplate和事务管理。
IOC:控制反转:把创建对象的过程交给Spring进行管理。
AOP:面向切面,不修改源代码进行功能增强
//Spring初体验 package com.sgyj.spring; public class User { public void add(){ System.out.println("add"); } } package com.sgyj.spring; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.applet.Applet; import java.applet.AppletContext; public class TestAdd { @Test public void add(){ ApplicationContext context= new ClassPathXmlApplicationContext("bean1.xml"); User user=context.getBean("user",User.class); System.out.println(user); } }
高屋建瓴:IOC底层实现主要是结合以下三种方式实现
Why:IOC容器的主要作用在于进行代码的解耦合
How:当我们使用Service类去调用Dao类时:
xml解析使用的时BeanFactory或者ApplicationContext
ApplicationContext context= new ClassPathXmlApplicationContext("bean1.xml");
IOC容器的基本实现,加载配置文件时候不会创建对象,在调用了getBean()方法后才去创建对象。
BeanFactory接口的子接口,加载配置文件的时候就会把配置文件的对象进行创建。
Spring中的bean有几种类型?区别是什么
Spring中有两种bean,一种是普通bean,另一种是工厂bean(FactoryBean)
普通bean是指:在配置文件中定义的bean类型就是返回类型
工厂bean是指:在配置文件中定义的bean类型可以与返回类型不一样
需要在xml文件中使用 <bean></bean>
创建对象
<bean id="user" class="com.sgyj.spring.User"></bean>
依赖注入的意思就是给对象设置相应的参数
关键字 property
<?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"> <!--> 使用set方法给dept注入属性<!--> <bean id="dep" class="com.sgyj.bean.Dep"> <property name="name" value="销售部"></property> </bean> </beans>
package com.sgyj.bean; import com.sgyj.Service.EmpService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Dep { private String name; public void setName(String name) { this.name = name; } @Test public void TestSet(){ //这里的getbean的第一个参数值 要和xml文件中 给dep起的别名一致 ApplicationContext context=new ClassPathXmlApplicationContext("bean3.xml"); Dep dep=context.getBean("dep",Dep.class); System.out.println(dep.name); } }
关键字:constructor-arg
public class Orders { //属性 private String oname; private String address; //有参数构造 public Orders(String oname,String address) { this.oname = oname; this.address = address; } }
<!--3 有参数构造注入属性--> <bean id="orders" class="com.atguigu.spring5.Orders"> <constructor-arg name="oname" value="电脑"></constructor-arg> <constructor-arg name="address" value="China"></constructor-arg> </bean>
关键字: xmlns:p=“http://www.springframework.org/schema/p”
<bean id="book" class="com.atguigu.spring5.Book" p:bname="九阳神功" p:bauthor="无名氏"></bean>
上面是我们正常创建对象时,注入正常的属性,下面演示如何注入其他属性
<property name="address"> <null/> </property>
实现:
(1)创建两个类service类和dao类
(2)在service调用dao里的方法
(3)在spring配置 文件中进行配置
配置
步骤一:在xml中分别配置servive与dao类对象的创建
步骤二:在service中注入dao对象,采用ref属性
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(); } } <!--1 service 和 dao 对象创建--> <bean id="userService" class="com.atguigu.spring5.service.UserService"> <!--注入 userDao 对象 name 属性:类里面属性名称 ref 属性:创建 userDao 对象 bean 标签 id 值 --> <property name="userDao" ref="userDaoImpl"></property> </bean> <bean id="userDaoImpl" class="com.atguigu.spring5.dao.UserDaoImpl"></bean>
(1)一对多关系:部门和员工 一个部门有多个员工,一个员工属于一个部门
部门是一,员工是多
(2)在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示
注入内部bean的意思就是在员工类中有部门类的实例,需要对员工类中的部门类进行注入属性
<bean id="emp" class="com.atguigu.spring5.bean.Emp"> <!--设置两个普通属性--> <property name="ename" value="lucy"></property> <property name="gender" value="女"></property> <!--设置对象类型属性--> <property name="dept"> <bean id="dept" class="com.atguigu.spring5.bean.Dept"> <property name="dname" value="安保部"></property> </bean> </property> </bean>
与注入内部bean意思差不多,这里采用注入外部类的方式实现
<bean id="emp" class="com.atguigu.spring5.bean.Emp"> <!--设置两个普通属性--> <property name="ename" value="lucy"></property> <property name="gender" value="女"></property> <!--级联赋值--> <property name="dept" ref="dept"></property> </bean> <bean id="dept" class="com.atguigu.spring5.bean.Dept"> <property name="dname" value="财务部"></property> </bean>
属性注入的代码
<bean id="stu" class="com.atguigu.spring5.collectiontype.Stu"> <!--数组类型属性注入--> <property name="courses"> <array> <value>java 课程</value> <value>数据库课程</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="PHP" value="php"></entry> </map> </property> <!--set 类型属性注入--> <property name="sets"> <set> <value>MySQL</value> <value>Redis</value> </set> </property> </bean>
将集合注入提取出来
(1)在 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:p="http://www.springframework.org/schema/p" 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">
(2)使用 util 标签完成 list 集合注入提取
<!--1 提取 list 集合类型属性注入--> <util:list id="bookList"> <value>易筋经</value> <value>九阴真经</value> <value>九阳神功</value> </util:list> <!--2 提取 list 集合类型属性注入使用--> <bean id="book" class="com.atguigu.spring5.collectiontype.Book"> <property name="list" ref="bookList"></property> </bean>
第一步:创建类,让这个类实现FactoryBean接口
第二部:实现接口里的方法,在实现的方法中定义返回的类型
1、创建类
public class MyBean implements FactoryBean<Course> { //定义返回 bean @Override public Course getObject() throws Exception { Course course = new Course(); course.setCname("abc"); return course; } @Override public Class<?> getObjectType() { return null; } @Override public boolean isSingleton() { return false; } }
2、配置xml文件
<bean id="myBean" class="com.atguigu.spring5.factorybean.MyBean"></bean>
3、测试
@Test public void test3() { ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml"); Course course = context.getBean("myBean", Course.class); System.out.println(course); }
注意:
1、如果是想要获取普通bean。配置文件中写的是MyBean,最终测试获取的对象就是mybean对象。而这里使用的是工厂Bean,所以获取到的返回值类型是Course 。
2、重写的getObject()的返回值类型设置为需要返回的类型,这里是想要 Course,所以返回值类型写Course
3、测试中,getBean中需要获取的是Course.class,写为Mybean.class会报错。
1、什么是作用域:Bean的作用域是指我们设置的Bean实例是单实例还是多实例
2、如何设置单实例和多实例:
3、单实例和多实例有什么区别
第一 singleton 单实例,prototype 多实例
第二 设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象
设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建 对象,在调用
getBean 方法时候创建多实例对象
1、通过调用无参构造函数创建bean对象
2、对Bean对象进行属性注入,调用set方法进行注入
3把bean实例传递给bean后置处理器的方法
4、执行bean的初始化方法
5、把bean的实例传递给bean后置处理器的方法
6、获取创建bean实例对象
7、执行销毁的方法
什么是自动装配:根据指定装配规则(属性名称或者属性类型),Spring 自动将匹配的属性值进行注入
<!--实现自动装配 bean 标签属性 autowire,配置自动装配 autowire 属性常用两个值: byName 根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样 byType 根据属性类型注入 --><bean id="emp" class="com.atguigu.spring5.autowire.Emp" autowire="byName"> <!--<property name="dept" ref="dept"></property>--> </bean> <bean id="dept" class="com.atguigu.spring5.autowire.Dept"></bean> (2)根据属性类型自动注入 <!--实现自动装配 bean 标签属性 autowire,配置自动装配 autowire 属性常用两个值: byName 根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样 byType 根据属性类型注入 --><bean id="emp" class="com.atguigu.spring5.autowire.Emp" autowire="byType"> <!--<property name="dept" ref="dept"></property>--> </bean> <bean id="dept" class="com.atguigu.spring5.autowire.Dept"></bean>
把外部 properties 属性文件引入到 spring 配置文件中
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" 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/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> ⚫ 在 spring 配置文件使用标签引入外部属性文件 <!--引入外部属性文件--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--配置连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${prop.driverClass}"></property> <property name="url" value="${prop.url}"></property> <property name="username" value="${prop.userName}"></property> <property name="password" value="${prop.password}"></property> </bean>
(1)@Component
(2)@Service
(3)@Controller
(4)@Repository
四个注解都可以来实现Bean对象的创建
之前对象的创建是通过xml文件中进行创建,现在只需要对需要创建的bean上面添加四个注解
@Service public class UserService { public void add(){ System.out.println("+++"); } public class demo1 { @Test public void test(){ ApplicationContext context=new ClassPathXmlApplicationContext("bean4.xml"); UserService userService=context.getBean("userService",UserService.class); userService.add(); } }
(1)@Autowired:根据属性类型进行自动装配
第一步 把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解
第二步 在 service 注入 dao 对象,在 service 类添加 dao 类型属性,在属性上面使用注解
@Service public class UserService { //定义 dao 类型属性 //不需要添加 set 方法 //添加注入属性注解 @Autowired private UserDao userDao; public void add() { System.out.println("service add......."); userDao.add(); } }
(2)@Qualifier:根据名称进行注入
这个@Qualifier 注解的使用,和上面@Autowired 一起使用
//定义 dao 类型属性 //不需要添加 set 方法 //添加注入属性注解 @Autowired //根据类型进行注入 @Qualifier(value = "userDaoImpl1") //根据名称进行注入 private UserDao userDao;
(3)@Resource:可以根据类型注入,可以根据名称注入
//@Resource //根据类型进行注入 @Resource(name = "userDaoImpl1") //根据名称进行注入 private UserDao userDao;
(4)@Value:注入普通类型属性
@Value(value = "abc") private String name;
不使用xml文件,创建配置类来替换xml配置文件。
@Configuration //作为配置类,替代 xml 配置文件 @ComponentScan(basePackages = {"com.atguigu"}) public class SpringConfig { }