spring
spring框架概述
是一个轻量级的开源的javaee框架(能够让开发更加方便,代码更加简介,帮你配置好没写好复杂的代码)
核心:
1.ioc:控制反转,把创建对象的过程交给spring 来处理
2.aop :面向切面,不修改源代码的情况下,来增强功能
特点:
1.方便解耦,简化开发
2.aop编程的支持
3.方便程序段的测试
4.方便和其他框架一起使用
5.降低javaee api的使用难度,方便进行事物的操作
使用
1.下载spring5的官网
核心jar包
ioc容器
概念:把对象的创建和调用都交给spring来管理,降低耦合度
实现原理:
1.xml解析,工厂模式,反射
IOC接口
1.IOC思想基于IOC容器实现,IOC容器底层就是对象工厂
2.spring提供了两种实现方式
1.BeanFactory:IOC容器基本实现,是spring内部的使用接口,不提供开发人员使用
加载配置文件时不会创建对象,只有在使用的时候才创建对象
2.applicationContext:是bean factory的子接口,开发人员使用,提供强大的功能
在加载配置文件的时候就会创建对象
application实现类:
IOC操作
1.Bean管理
1.spring创建对象
2.用Spring注入属性:将类对应的属性
2.bean管理操作方式
1.基于xml配置文件
1.基于xml创建对象
bean里面常用的属性:
id属性:表示给对象起一个别名,用来找到相关联类
class属性:写要创建对象类的全路径
创建对象时会调用默认的无参构造
name:和id的作用类似,但name里面可以添加特殊符号,id里面不可以
2.基于xml注入属性
1.DI:依赖注入(注入属性)是IOC中的一种具体实现
2.普通方式:通过set方法进行注入,通过有参数的构造方法
set方法创建
student类中要有set方法
构造方法注入
<bean id="student" class="com.lxy.spring.Student">
<constructor-arg name="username" value="你好"></constructor-arg>
</bean>
name是属性名称,value是属性值
还可以把name换成index 0代表第一个属性
使用p名称注入
第一步:
xmlns:p="http://www.springframework.org/schema/p"
第二部:
<bean id="student" class="com.lxy.spring.Student" p:username="王小美"></bean>
xml注入其他类型属性(空值和特殊字符)
1.注入空值
<bean id="student" class="com.lxy.spring.Student">
<property name="username">
<null></null>
</property>
</bean>
2.注入特殊属性
<bean id="student" class="com.lxy.spring.Student">
<property name="username">
<value><![CDATA[《斗破苍穹》]]></value>
</property>
</bean>
注入属性-外部bean
(1)创建两个类service和dao类
(2)在service调用到里面的方法
(3)在spring配置文件中进行配置
将类注入到另一个类中
<bean id="userservice" class="com.lxy.spring.service.UserService">
<property name="userDao" ref="userdao"></property>
</bean>
<bean id="userdao" class="com.lxy.spring.dao.UserDaoImp"></bean>
注入属性-内部bean
<bean id="emp" class="com.lxy.spring.bean.Emp">
<property name="sex" value="男"></property>
<property name="username" value="lxy"></property>
<property name="dept" >
<bean id="dept" class="com.lxy.spring.bean.Dept">
<property name="dname" value="软件部门"></property>
</bean>
</property>
</bean>
//在bean里面创建写bean
级联赋值
通过对象.属性来赋值,但是对象要有相应的get方法
xml注入集合属性
1.注入数组
2.注入list集合属性
3.注入map集合
<!-- 对象创建-->
<bean id="stu" class="com.lxy.spring.collectiontype.Stu">
<!-- 数组内容注入-->
<property name="courses" >
<array>
<value>语文</value>
<value>数学</value>
<value>英语</value>
</array>
</property>
<!-- list集合注入-->
<property name="list">
<list>
<value>h</value>
<value>e</value>
<value>l</value>
</list>
</property>
<!-- map集合注入-->
<property name="map">
<map>
<entry key="语文" value="80"></entry>
<entry key="数学" value="90"></entry>
</map>
</property>
<!-- set集合注入-->
<property name="set">
<set>
<value>1</value>
<value>2</value>
</set>
</property>
细节问题
1.如何在集合里面注入对象
<property name="mycourse">
<array>
<ref bean="math"></ref>
<ref bean="chinese"></ref>
</array>
</property>
<!-- 创建多个course对象-->
<bean id="math" class="com.lxy.spring.collectiontype.Course">
<property name="coursename" value="数学"></property>
</bean>
<bean id="chinese" class="com.lxy.spring.collectiontype.Course">
<property name="coursename" value="语文"></property>
</bean>
提取list集合
1.在spring配置文件中映入util
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.使用utli标签完成list集合的注入
<util:list id="booklist">
<value>盗墓笔记</value>
<value>完美世界</value>
<value>吞噬星空</value>
</util:list>
<bean id="book" class="com.lxy.spring.collectiontype.Book">
<property name="list" ref="booklist">
</property>
</bean>
FactoryBean
1.spring有两个bean
1我们平时使用的bean:在配置文件中class文件中定义的类型就是返回值类型
2.工厂bean:在配置文件中class文件中定义的类型可以不一样
使用:
1.创建类,实现FactoryBean接口
2.实现接口里面的方法
public class MyBean implements FactoryBean<Course> {
//定义返回类型
@Override
public Course getObject() throws Exception {
Course course = new Course();
course.setCoursename("你好");
return course;
}
@Override
public Class<?> getObjectType() {
return null;
}
public void fun(){
System.out.println("测试");
}
}
@Test
public void test2(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
Course mybean = context.getBean("mybean", Course.class);
System.out.println(mybean.toString());
}
bean的作用域
1.在spring中可以设置是单实例还是多实例,默认是单实例
设置是单实例还是多实例
scope实行来设置
scope="singleton":表示是一个单实例对象,默认值,加载spring的配置文件时就会创建相应对象
scope="prototype":多实例对象,在调用getbean方法时在创建新的对象
request:表示是reques
session:会把类加载到session里面
bean的生命周期
1.生命周期:从一个对象的创建到销毁的过程
bean的生命周期:1.通过构造器创建bean实例2.为bean里面的属性注入属性(调用set方法)
2.调用bean为初始化方法(进行响应配置)
init-method="init"
4.使用
5.当容器关闭的时候清除bean
bean的自动装配
1.根据指定装配规则(属性名称和属性类型),spring自动匹配的属性值进行注入
//根据属性名称进行自动装配(配置的类型名称要和属性名称相同)
<bean id="emp" class="com.lxy.spring.autowrite.Emp" autowire="byName"></bean>
//根据属性类型进行注入(想同类型的bean不能创建多个)
<bean id="emp" class="com.lxy.spring.autowrite.Emp" autowire="byType"></bean>
外部属性文件
1.配置德鲁伊连接池
1.引入德鲁伊jar包
2.
2.引入外部属性文件配置连接池
bean注解(对象创建和注入属性)
注解:代码里面的特殊标记
注解的使用位置:可以作用在类,方法属性里面
注解:简化xml配置
创建对象注解:@Component @Service @Controller @Repository
上面注解的效果是一样的
注解使用:、
1.引入依赖:aop
2.开启组件扫描:告诉要扫描的类,如果要扫描多个包,那么就用,隔开或者上层目录
<context:component-scan base-package="com.lxy.spring"></context:component-scan>
3.创建类在类上面加上注解
@Component(value = "userService")
测试使用
public class demo01 {
@Test
public void test(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.add();
}
}
扫描的细节处理
use-default-filters="false"
//表示不使用默认的filter使用我们直接配置的规则
表示不会从com.atguigu包扫描而是从带有controller注解的类扫描
扫描包里所有的包设置是controller注解不扫描
基于注解方式进行属性注入
1.先用注解配置userdao和service独享
2.在service里面添加userdao双属性
3.在userdao属性上庙添加注解(不需要使用set方法默认封装)
@autowired:根据属性类型进行自动注入
@qualifier:根据属性名称注入
qualifier要和autowired一起使用
@Autowired
@Qualifier(value = "userDaoImp")
//userDaoImp要和类注解的名称一样
@resource:既可以属性注入也可以名称注入
@Resource
//表示根据类型进行注入
@Resource(name = "userDaoImp")
//表示根据名字注入,name的值要和类注解的名称一样
@value表示普通属性注入
@Value(value = "hello")
private String name;
完全注解开发
1.创建配置类(替代xml里面的配置文件)
@Configuration//把当前类作为配置类
@ComponentScan(basePackages = "com.lxy.spring")//相当于扫描的包
public class SpringConfig {
}
test类里面的写法
public void test1(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);//里面的参数是config类文件
UserService userService = context.getBean("userService", UserService.class);
userService.add();
}
aop
概念:面向切面编程,对业务的逻辑进行隔离减低耦合度,提高可操作性,不修改源代码来添加功能
底层原理:使用动态代理:
两种情况的动态dialing
1.有接口的情况,使用jdk动态代理
2,。没有接口的情况,使用cglib代理增强
AOP相关术语
1.连接点:类里面的哪些方法可以被增强
2.切入点:实际被真正增强的方法,称为接入点
3.通知(增强):真正被增强的部分被称为通知
类型:
1.前置通知:在要增强的方法之前执行
2.后置通知:在要增强的方法之后执行
3.环绕通知:在要增强的方法前面和后面都要执行
4.异常通知:当要执行的方法出现了异常
5.最终通知:finally
4.切面:(动作)把通知应用到切入点
aop操作(准备)
1.spring基于aspectJ实现aop操作
AspectJ:不是spring的一部分,而是独立的一部分,一般和spring一起使用来操作aop
2.方法
1.基于xml方式实现
2.基于注解实现
3.在项目工程中引入依赖
4.切入点表达式
作用:知道对那个类中的那个方法进行增强
语法结构:
execution(权限修饰符,返回类型,类全路径,方法名称,参数列表)
AspectJ注解
1.创建类,定义方法
2.创建增强类(编写增强的逻辑)
3.进行通知的配置
1.在spring配置文件中开始扫描
2.使用注解创建你user和userproxy的对象
3.在增强类上加@aspect注解
4.在spring中开启生成代理对象
相同切入点抽取
//相同切入点抽取
@Pointcut(value = "execution(* com.lxy.spring.apoann.User.add(..))")
public void pointdemo(){
}
@Before(value = "pointdemo()")
public void before(){
System.out.println("执行前方法");
}
如果有两个类都对一个方法进行增强可以设置优先级
1.在增强类上面加上注解@Order(值)值越小优先级越高
jdbc模板
JDBCTemplate
1.spring框架里面对jdbc进行封装,使用jdbctemplate实现对数据库的操作
准备工作:
1.引入相关的jar包
类型,类全路径,方法名称,参数列表)
AspectJ注解
1.创建类,定义方法
2.创建增强类(编写增强的逻辑)
3.进行通知的配置
1.在spring配置文件中开始扫描
2.使用注解创建你user和userproxy的对象
3.在增强类上加@aspect注解
4.在spring中开启生成代理对象
相同切入点抽取
//相同切入点抽取
@Pointcut(value = "execution(* com.lxy.spring.apoann.User.add(..))")
public void pointdemo(){
}
@Before(value = "pointdemo()")
public void before(){
System.out.println("执行前方法");
}
如果有两个类都对一个方法进行增强可以设置优先级
1.在增强类上面加上注解@Order(值)值越小优先级越高
jdbc模板
JDBCTemplate
1.spring框架里面对jdbc进行封装,使用jdbctemplate实现对数据库的操作
准备工作:
1.引入相关的jar包