Spring-Study
Posted 轻舟一曲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring-Study相关的知识,希望对你有一定的参考价值。
常用依赖
pom.xml
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
beans.xml注解支持
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
">
<!--开启注解的支持-->
<context:annotation-config/>
</beans>
spring-dao.xml
dataSource和sqlSession的Spring方式注入
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&
characterEncoding=UTF- 8&allowPublicKeyRetrieval=true"/>
<property name="username" value="root"/>
<property name="password" value="8613919"/>
</bean>
<!-- sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 绑定mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath*:com/mf/dao/**/*.xml"/>
</bean>
<!-- SqlSessionTemplate就是我们使用的sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!-- 只能使用构造器注入sqlSessionFactory,因为他没有set方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
目录
Spring
简介
spring理念:使现有技术更加实用,本身就是一个大杂烩,整合现有的框架技术。
一句话概括:spring是一个轻量级的控制反转Ioc和面向切面AOP的容器(框架)。
优点
- 轻量级,非入侵;
- 控制反转,面向切面;
- 支持事务处理,对象框架整合。
拓展
IOC理论推导
spring7层分层架构:
**核心容器:**通过beanfactory使用控制反转定义创建、配置、管理bean的方式。
spring上下文:配置文件,提供一些企业服务。
**springAOP:**将声明性事务切入应用程序。
**springDAO:**面向 JDBC 的异常,降低了需要编写的异常代码数量(例如打开和关闭连接)。
Spring ORM:若干个 ORM 框架。
Spring Web 模块:为基于 Web 的应用程序提供了上下文
Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。
1.ApplicationContext.xml读取配置文件
2.POJO根据元数据创建和组装Bean
3.程序使用时再从Ioc容器中取出需要的对象
Ioc实现方式有两种:xml配置和注解
采用xml配置,bean的定义信息和实现分离;
注解把二者合二为一,定义信息直接以注解形式在实现类中,从而达到零配置。
IOC的本质
控制反转的本质是一种设计思想,DI(依赖注入)是实现IOC的一种方式。
- UserDao接口
- UserDaoImpl实现类
- UserService业务接口
- UserServiceImpl业务实现
HelloSpring
1.创建实体,创建接口和实现类
2.注册beans.xml,交由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就是java对象 , 由Spring创建和管理-->
<bean id="hello" class="com.kuang.pojo.Hello">
<property name="name" value="Spring"/>
</bean>
<bean id="MysqlImpl" class="com.kuang.dao.impl.UserDaoMySqlImpl"/>
<bean id="OracleImpl" class="com.kuang.dao.impl.UserDaoOracleImpl"/>
<bean id="ServiceImpl" class="com.kuang.service.impl.UserServiceImpl">
<!--注意: 这里的name并不是属性 , 而是set方法后面的那部分 , 首字母小写-->
<!--引用另外一个bean , 不是用value 而是用 ref-->
<property name="userDao" ref="OracleImpl"/>
</bean>
</beans>
3.要用直接ApplicationContext 从beans.xml拿到(再也不用new 对象了)
IOC创建对象的方式
1.通过无参构造方法来创建。
2.通过有参构造方法(还是用Set方法)来创建。
beans.xml参数设置3种方式:
1.根据index参数下标。
2.根据参数名字。推荐使用
3.根据参数类型。不建议使用
<constructor-arg index="0" value="kuangshen2"/>
<property name="name" value="马富说"/>
<constructor-arg type="java.lang.String" value="kuangshen2"/>
配置文件加载的时候,其中管理的对象已经创建和初始化了。
传统对象由程序本身控制创建。
spring由IOC容器创建对象并设置属性,程序本身不创建对象而是被动接受对象,利用set方法进行注入,这个过程就叫做控制反转。
Spring配置
别名alias
Bean配置
id是bean的标识符,要唯一;
没有配置id,name就是默认标识符;
有id又有name,name就是别名;
两个都没有,applicationContext.getBean(.class)获取对象。
<bean id="hello" name="hello2 h2,h3;h4" class="com.kuang.pojo.Hello">
<property name="name" value="Spring"/>
</bean>
import
依赖注入
依赖IOC容器创建对象,注入对象属性值。
构造器注入
Set方式注入【重点】
拓展方式注入
1.常量注入
2.bean注入 ref
3.数组注入 array
4.list注入 list
5.Map注入 map entry
6.set注入 set
7.null注入
8.properties注入 props prop
p标签注入(set方式注入)
c标签注入(有参构造方式注入)
bean的作用域
单例 singleton
原生型 score=prototype
request创建自己的bean
session共享bean
Bean自动装配
spring装配bean方式有三种:
1.java中显示配置
2.xml中显示配置
3.隐式bean发现机制和自动装配(组件扫描component scanning,自动装配autowiring)
什么叫自动装配:spring自动发现应用上下文所创建的bean,spring自动满足bean之间的依赖。
自动装配有3种方式:
byname
bytype
注解(推荐使用)
xml以前的bean装配方式
ByName自动装配,ByType自动装配
<!--原来的方式-->
<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User">
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
<property name="str" value="qinjiang"/>
</bean>
<!--byname自动装配-->
<bean id="user" class="com.kuang.pojo.User" autowire="byName">
<property name="str" value="qinjiang"/>
</bean>
<!--bytype自动装配,类型要唯一-->
<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<!--类型不唯一报错-->
<bean id="cat2" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User" autowire="byType">
<property name="str" value="qinjiang"/>
</bean>
使用注解实现自动装配(推荐使用)
导使用注解就需要导入spring-aop的包
开启注解支持
<context:annotation-config/>
@Autowired是按类型自动装配的,不支持id匹配
//如果允许对象为null,设置required = false,默认为true
@Autowired(required = false)
private Cat cat;
@Autowired
private Dog dog;
private String str;
<context:annotation-config/>
<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User"/>
@Autowired加上 @Qualifier可以根据byname自动装配,就可以支持id匹配了
@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;
@Resource
如有指定的name属性,先按该属性进行byName方式查找装配;
其次再进行默认的byName方式进行装配;
其次再按byType的方式自动装配。
@Resource
private Cat cat;
@Resource
private Dog og;
基于注解开发spring
导入注解支持包aop 和 context约束
扫描包 和 添加注解驱动
<context:component-scan base-package="com.kuang.pojo"/>
<context:annotation-config/>
包下的类增加注解@Component,属性注入 @Value(如果提供了set方法,在set方法上添加@value(“值”)
@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
@Value("秦疆")
// 相当于配置文件中 <property name="name" value="秦疆"/>
public String name;
}
不同层的衍生注解:本质都是@component
- @controller :web层
- @service:service层
- @repository:dao层
bean的自动装配上节已讲。
小结:
xml与注解比较:
-
xml适用任何场景,结构清晰,维护方便
-
注解不是自己提供的类适用不了,开发方便
**推荐使用xml和注解整合开发:**xml管理bean,注解完成属性注入
基于Java类开发spring
编写实体类
创建config配置包,编写配置类
@Configuration //代表这是一个配置类
public class MyConfig {
@Bean //通过方法注册一个bean,这里的返回值就Bean的类型,方法名就是bean的id!
public Dog dog(){
return new Dog();
}
}
@Test
public void test2(){
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MyConfig.class);
Dog dog = (Dog) applicationContext.getBean("dog");
System.out.println(dog.name);
}
@Import(MyConfig2.class) //导入合并其他配置类,类似于配置文件中的 inculde 标签
代理模式
静态代理
1.抽象角色
2.具体角色
3.代理角色
4客户
缺点:增加具体角色要增加代理类,工作量变大,改动功能需要改动代码量大,违反开闭原则。
动态代理
动态代理分两类:基于接口(JDK动态代理)和基于类(cglib) 。
现在比较多使用javasist生成动态代理。
基于JDK动态代理
两个核心类
InvocationHandler:调用处理程序
Proxy :实现了接口InvocationHandler
Proxy
提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。
两个重要方法:
getProxy() : newProxyInstance(loader,interfaces,h);
loader-类加载器来定义代理类
interfaces-代理类实现接口列表
h-调度方法调用的调用处理函数
invoke() : 处理代理实例上的方法调用并返回结果
//生成代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(),this);
}
public class ProxyInvocationHandler implements InvocationHandler {
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(),this);
}
// proxy : 代理类
//method : 代理类的调用处理程序的方法对象.
// 处理代理实例上的方法调用并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
//核心:本质利用反射实现!
Object result = method.invoke(rent, args);
fare();
return result;
}
//看房
public void seeHouse(){
System.out.println("带房客看房");
}
//收中介费
public void fare(){
System.out.println("收中介费");
}
}
//代理实例的调用处理程序
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setRent(host); //将真实角色放置进去!
Rent proxy = (Rent)pih.getProxy(); //动态生成对应的代理类!
动态代理代理某一类业务
一个动态代理可以代理多个类,代理的是接口!
动态代理固定模板
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
//生成代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
// proxy : 代理类
// method : 代理类的调用处理程序的方法对象.
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(target, args);
return result;
}
public void log(String methodName){
System.out.println("执行了"+methodName+"方法");
}
}
//真实角色
UserServiceImpl userService = new UserServiceImpl();
//代理角色,不存在
ProxyInvocationHandler pih = new ProxyInvocationHandler();
//设置要代理的对象
pih.setTarget(userService);
UserService proxy =(UserService) pih.getProxy();
proxy.add();
proxy.delete();
AOP
纵向开发:
dao
|
service
|
servlet
|
前端
横向开发:
log->userservice
面向切面编程: 不改变原来的代码的情况下,实现了对原有功能的增强。
springaop:提供声明式事务,允许用户自定义切面。
通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
切入点(PointCut):切面通知 执行的 “地点”的定义。
五种类型的Advice
1.前置通知
2.后置通知
3.环绕通知
4.异常抛出通知
5.引介通知
AOP三种实现方式
导入aop织入包
SpringAPI实现
以上是关于Spring-Study的主要内容,如果未能解决你的问题,请参考以下文章