1.Spring
1.1简介
- 2002年,首次推出Spring框架的雏形:interface21框架
- Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于*2004年3月24日,*发布了1.0正式版。
- Rod Johnson ,Spring Framework创始人,著名作者。很难想象Rod Johnson的学历,真的让好多人大吃一惊,他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。
- spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架!
下载地址:
- 官网:https://spring.io/projects/spring-framework#overview
- 官方下载地址: http://repo.spring.io/release/org/springframework/spring
- GitHub:https://github.com/spring-projects/spring-framework
1.2优点
- Spring是一个开源的免费的框架(容器)!
- Spring是一个轻量级的、非入侵式的框架!
- 控制反转(IOC) , 面向切面编程(AOP)!
- 支持事务的处理,对框架整合的支持!
总结:spring是一个轻量级的控制反转(IOC)面向切面编程(AOP)的框架
1.3组成
1.4拓展
在Spring的官网有这个介绍:现代化的Java开发!就是基于Spring的开发!
- Spring Boot
- 一个快速开发的脚手架。
- 基于SpringBoot可以快速的开发单个微服务。
- 约定大于配置!
- Spring Cloud
- SpringCloud 是基于SpringBoot实现的。
2.IOC理论推导
分层开发:
- dao层
- UserDao接口
- UserDaoImpl 1
- UserDaoImpl 2
- … 有多个实现类
- service
- UserService接口
- User ServiceImpl
我们通过UserServiceImpl来调用dao层,但是dao曾有多个实现类,我们需要修改SeviceImpl中的代码来实现不同的dao实现类的调用。控制权在业务层 在程序员手中。
如果我们在serviceImpl中通过set传入userDao,业务层不用去知道dao具体实现的类,这个交给用户,用户传入哪个就用哪个。将控制权交给用户。
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建了。系统的耦合性大大降低~,可以更加专注的在业务的实现上!这是IOC 的原型!
2.1IOC本质
控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
3.HelloSpring
3.1导入spring相关jar包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.2</version>
</dependency>
3.2创建applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
3.3编写相关代码
3.3.1编写实体类
package com.mahui.pojo;
public class Hello {
private String string;
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
@Override
public String toString() {
return "Hello{" +
"string='" + string + '\'' +
'}';
}
}
3.3.2编写bean
在applicationContext.xml中编写bean
<bean id="hello" class="com.mahui.pojo.Hello">
<!--name:属性名 value:属性值-->
<property name="string" value="Spring"/>
</bean>
3.3.3测试
public class MyTest {
public static void main(String[] args) {
//通过ClassPathXmlApplicationContext加载配置
ApplicationContext Context = new ClassPathXmlApplicationContext("beans.xml");
//从容器中拿出对象
Hello hello = (Hello) Context.getBean("hello");
System.out.println(hello.toString());
}
3.4思考问题?
-
hello 对象谁创建的?
hello是由spring创建的
-
hello对象的属性是怎么设置的?
hello对象的属性是由spring属性设置的
这个过程成为控制反转:
- 控制:谁来控制对象的创建,传统的应用程序的对象是由程序本身创建的,但是使用spring之后,对象是由spring创建
- 反转:程序本身不创建对象,而变成被动的接收对象
- 依赖注入:利用set方法进行注入
- IOC是一种编程思想,有主动的编程,变为被动的接收,即对象由spring创建管理和装配
4.IOC创建对象的方式
4.1通过无参构造创建(默认)
<bean id="user" class="com.mahui.pojo.User">
<property name="name" value="小明"/>
</bean>
4.2通过有参构造创建
4.2.1 通过参数类型
不建议使用通过参数类型来
通过参数类型创建对象
<bean id="user" class="com.mahui.pojo.User">
<constructor-arg type="java.lang.String" value="小红"/>
</bean>
4.2.2通过参数的下标
通过参数下标创建对象
<bean id="user" class="com.mahui.pojo.User">
<constructor-arg index="0" value="小名"/>
</bean>
4.2.3通过参数名来创建
<!--通过参数名字创建对象-->
<bean id="user" class="com.mahui.pojo.User">
<constructor-arg name="name" value="小张"/>
</bean>
5.Spring配置
5.1 别名
<!--添加了别名,我们可以通过别名获得这个对象,也可以通过其原来的名字获得对象-->
<alias name="user" alias="user2"/>
5.2Bean的配置
<!--
id :bean的唯一标识,也就是对象名
class:bean对象所对应的全限定名:包名+类型
name:也就是别名 可以同时取多个别名
-->
<bean id="user" class="com.mahui.pojo.User" name="user3 user4;u5,u6">
<property name="name" value="小明"/>
</bean>
5.3import
import一般用于团队开发,可以将多个配置文件 ,导入并合并为一个配置文件
- applicationContext.xml
<import resource="beans.xml"/>
<import resource="beans1.xml"/>
<import resource="beans2.xml"/>
<import resource="beans3.xml"/>
使用的时候使用总的xml配置就可以了。
6.依赖注入
6.1构造器注入
上边ioc创建对象的方式已经写过
6.2set方式注入
- 依赖注入
- 依赖:bean对象的创建依赖于容器
- 注入:bean对象的属性由容器注入
6.2.1创建复杂环境
address
package com.mahui.pojo;
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Address{" +
"address='" + address + '\'' +
'}';
}
}
people
package com.mahui.pojo;
import java.util.*;
public class People {
private String name;
private Address address;
private String[] books;
private List<String> hobbys;
private Map<String,String> card;
private Set<String> games;
private String wife;
private Properties info;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String[] getBooks() {
return books;
}
public void setBooks(String[] books) {
this.books = books;
}
public List<String> getHobbys() {
return hobbys;
}
public void setHobbys(List<String> hobbys) {
this.hobbys = hobbys;
}
public Map<String, String> getCard() {
return card;
}
public void setCard(Map<String, String> card) {
this.card = card;
}
public Set<String> getGames() {
return games;
}
public void setGames(Set<String> games) {
this.games = games;
}
public String getWife() {
return wife;
}
public void setWife(String wife) {
this.wife = wife;
}
public Properties getInfo() {
return info;
}
public void setInfo(Properties info) {
this.info = info;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", address=" + address.toString() +
", books=" + Arrays.toString(books) +
", hobbys=" + hobbys +
", card=" + card +
", games=" + games +
", wife='" + wife + '\'' +
", info=" + info +
'}';
}
}
6.2.2xml中注入
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="address" class="com.mahui.pojo.Address" >
<property name="address" value="陕西西安"/>
</bean>
<bean id="people" class="com.mahui.pojo.People">
<!--普通注入-->
<property name="name" value="张三"/>
<!--bean注入-->
<property name="address" ref="address"/>
<!--数组-->
<property name="books">
<array>
<value>活着</value>
<value>平凡的世界</value>
<value>自在独行</value>
</array>
</property>
<!--List-->
<property name="hobbys">
<list>
<value>听歌</value>
<value>玩游戏</value>
</list>
</property>
<!--set-->
<property name="games">
<set>
<value>cf</value>
<value>lol</value>
</set>
</property>
<!--map-->
<property name="card">
<map>
<entry key="身份证" value="11111"/>
<entry key="银行卡" value="11111"/>
</map>
</property>
<!--null-->
<property name="wife" >
<value>null</value>
</property>
<property name="info">
<props>
<prop key="driver">12233</prop>
<prop key="root">12233</prop>
<prop key="password">12233</prop>
</props>
</property>
</bean>
</beans>
6.2.3测试
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
People people = (People) context.getBean("people");
System.out.println(people.toString());
}
}
6.3拓展方式注入
可以使用p命令空间和c命令空间进行注入:
在使用c命令空间跟p命令空间 需要导入xml约束!
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
使用:
p命令空间
<!--p命令空间注入可以直接注入属性的值:properties-->
<bean id="people" class="com.mahui.pojo.People" p:name="张三"/>
c命令空间
<!--c命令空间注入通过构造器注入 construct-args-->
<bean id="people" class="com.mahui.pojo.People" c:name="张三"/>
6.4bean作用域
6.4.1单例模式(Spring默认机制)
<bean id="people" class="com.mahui.pojo.People" p:name="张三" scope="singleton"/>
6.4.2原型模式:每次从容器中get的时候,都会产生一个新的对象。
<bean id="people" class="com.mahui.pojo.People" p:name="张三" scope="prototype"/>
6.4.3其余的request、session、application,这些只能在web开发中使用dao
7.bean的自动装配
7.1创建环境
实体类
cat
public class Cat {
public void show(){
System.out.println("miao~");
}
}
dog
public class Dog {
public void show(){
System.out.println("wang~");
}
}
people
public class People {
private String name;
private Cat cat;
private Dog dog;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
7.2ByName自动装配
<bean id="cat" class="com.mahui.pojo.Cat"/>
<bean id="dog" class="com.mahui.pojo.Dog"/>
<bean id="people" class="com.mahui.pojo.People" autowire="byName">
<property name="name" value="张三"/>
</bean>
7.3ByType自动装配
<bean id="cat" class="com.mahui.pojo.Cat"/>
<bean id="dog" class="com.mahui.pojo.Dog"/>
<bean id="people" class="com.mahui.pojo.People" autowire="byType">
<property name="name" value="张三"/>
</bean>
7.4使用注解实现自动装配
7.4.1导入约束:context约束
7.4.2配置注解支持:context:annotation-config/
<?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"
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">
<!--开启支持注解开发-->
<context:annotation-config/>
</beans>
7.4.3@Autowired
可以直接在属性上使用,也可以在set方法上使用,使用Autowired可以不用写set方法,前提是这个自动装配的属性存在IOC(Spring)容器中
测试:
如果@Autowired自动装配的环境比较复杂,我们可以使用 @Qualifier(“XXX”)去配置,指定唯一的bean对象注入
public class People {
private String name;
//@Autowired(required =false) required=false 说明这个字段可以为null否则不能为空
@Autowired
@Qualifier("cat")
private Cat cat;
@Autowired
@Qualifier("dog")
private Dog dog;
}
7.4.4@Resource
public class People {
private String name;
@Resource(name = "cat")
private Cat cat;
@Resource
private Dog dog;
}
总结:
@Autowired和@Resource的区别:
- 都可以使用自动装配,都可以放在属性ziduanshang
- @Autowired 通过byType的方式实现,而且必须要求这个对象存在
- @Resource默认通过byName的方式实现,如果找不到名字通过byType实现,如果两个都找不到的情况就会报错!
8.使用注解开发
在Spring4之后,要使用注解开发必须要确保aop包的导入
使用注解开发,必须在xml文件中导入context约束,增加注解支持,
<?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"
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">
<!--指定扫描的包,这个包下的注解就会生效-->
<context:component-scan base-package="com.mahui.pojo"/>
<!--开启支持注解开发-->
<context:annotation-config/>
</beans>
1.bean
2.属性如何注入
package com.mahui.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class User {
//相当于 <property name="name" value="张三"/>
@Value("张三")
private String name;
public String getName() {
return name;
}
}
3.衍生注解
在web的开发中我们按照mvc三层构造分层,@Component有几个衍生的注解
- dao【@Repository】
- service 【@Service】
- controller【@Controller】
这四个注解的功能都是一样的,都代表某个类注册到Spring中,装配bean
4.自动装配
5.作用域
package com.mahui.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
//@Scope("singleton")
public class User {
//相当于 <property name="name" value="张三"/>
@Value("张三")
private String name;
public String getName() {
return name;
}
}
6.总结
xml与注解:
- xml适用于任何的场合,维护简单方便
- 注解不是自己类使用不了,维护相对复杂
xml与注解最佳实践:
-
xml用来管理bean
-
注解只是负责完成属性的注入
-
在使用的过程中,不需要让注解生效
<!--指定扫描的包,这个包下的注解就会生效--> <context:component-scan base-package="com.mahui.pojo"/> <!--开启支持注解开发--> <context:annotation-config/>
9.使用java的方式配置spring
实体类:
package com.mahui.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component//这个类被spring接管了,注册到容器中
public class User {
@Value("张三")//属性注入值
private String name;
public String getName() {
return name;
}
}
配置类:
package com.mahui.config;
import com.mahui.pojo.User;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
//@Configurable 代表一个配置类相当于之前的applactionContext.xml
@Configurable
@ComponentScan("com.mahui.pojo")
@Import(MyConfig2.class)
public class MyConfig {
//注册一个bean,相当于之前写的bean标签
//这个方法的名字就是之前bean标签的id属性
//这个方法的返回值,就相当于bean标签中的class属性
@Bean
public User getuser(){
return new User();
}
}
测试类:
import com.mahui.config.MyConfig;
import com.mahui.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
public static void main(String[] args) {
//通过AnnotationConfigApplicationContext来获取容器,通过配置类的class对象加载。
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = (User) context.getBean("getuser");
System.out.println(user.getName());
}
}
10.代理模式
10.1静态代理
角色分析:
- 抽象角色:一般会使用接口或者抽象类来解决。
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理真实角色之后会做一些附加操作
- 客户:访问代理对象的
以租房为例:
- 抽象角色:租房这件事
- 真实角色:房东有房子出租
- 代理角色:中介,会帮房东把房子租出去,并且自己会抽取中介费,带客户看房子等等
- 客户:要租房子的人
1.抽象角色
public interface Rent {
//租房子的接口
public void rent();
}
2.真实角色
public class Host implements Rent{
//真实的角色:实现代理接口
public void rent() {
System.out.println("我有房子需要出租");
}
}
3.代理角色
public class Proxy implements Rent {
//将需要被代理的真实角色传入
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void rent() {
//中介代理出租房子
host.rent();
seeHouse();
hetong();
fare();
}
//中介也有自己的一些方法
//中介带你去看房子
public void seeHouse(){
System.out.println("看房子");
}
//签订合同
public void hetong(){
System.out.println("签订合同");
}
//收取中介费
public void fare(){
System.out.println("收取中介费");
}
}
4.客户
package com.mahui.demo01;
public class Client {
public static void main(String[] args) {
//一个房东
Host host = new Host();
//中介 代理房东去租赁房子
Proxy proxy = new Proxy(host);
//只需要找中介就能租到房子
proxy.rent();
}
}
代理模式的优点:
- 可以使真实角色的操作更加纯粹,不去关注一些公共的业务
- 公共业务交给代理角色,实现了业务的分工
- 公共业务发生扩展时方便集中管理
代理模式的缺点:
- 一个真实角色就会产生一个代理角色,开发效率低
10.2动态代理
通过反射动态生成代理类:
11.aop
11.1什么是aop
AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
11.2aop在spring中的作用
提供声明式事务;允许用户自定义切面
-
横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 …
-
切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
-
通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
-
目标(Target):被通知对象。
-
代理(Proxy):向目标对象应用通知之后创建的对象。
-
切入点(PointCut):切面通知 执行的 “地点”的定义。
-
连接点(JointPoint):与切入点匹配的执行点。
SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:
即 Aop 在 不改变原有代码的情况下 , 去增加新的功能 .
11.3使用spring实现aop
使用aop织入必须要导的jar包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
11.3.1 aop实现方式一api接口
1.抽象角色
package com.mahui.service;
public interface UserService {
public void add();
public void update();
public void select();
public void delete();
}
2.真实角色
package com.mahui.service;
public class UserServiceImpl implements UserService {
public void add() {
System.out.println("增加了一个用户");
}
public void update() {
System.out.println("更新了一个用户");
}
public void select() {
System.out.println("查询了一个用户");
}
public void delete() {
System.out.println("删除了一个用户");
}
}
3.切入的内容
执行前
package com.mahui.log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class BeforeLog implements MethodBeforeAdvice {
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println(method.getName()+"方法执行前");
}
}
执行后
package com.mahui.log;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice {
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println(method.getName()+"方法执行后");
}
}
4.在applicationContext.xml中配置
<!--注册类-->
<bean id="userservice" class="com.mahui.service.UserServiceImpl"/>
<bean id="beforelog" class="com.mahui.log.BeforeLog"/>
<bean id="afterlog" class="com.mahui.log.AfterLog"/>
第一种方式
<aop:config>
<!--设置切入点execution执行的位置(* com.mahui.service.UserServiceImpl.*(..)) 修饰词 返回值 类名 方法名 参数 -->
<aop:pointcut id="ponintcut" expression="execution(* com.mahui.service.UserServiceImpl.*(..))" />
<!--切入的内容-->
<aop:advisor advice-ref="beforelog" pointcut-ref="ponintcut"/>
<aop:advisor advice-ref="afterlog" pointcut-ref="ponintcut"/>
</aop:config>
5.测试:
import com.mahui.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userservice = (UserService) context.getBean("userservice");
userservice.delete();
}
}
11.3.2 aop实现方式二自定义
1.抽象角色
package com.mahui.service;
public interface UserService {
public void add();
public void update();
public void select();
public void delete();
}
2.真实角色
package com.mahui.service;
public class UserServiceImpl implements UserService {
public void add() {
System.out.println("增加了一个用户");
}
public void update() {
System.out.println("更新了一个用户");
}
public void select() {
System.out.println("查询了一个用户");
}
public void delete() {
System.out.println("删除了一个用户");
}
}
3.自定义的插入类
package com.mahui.diy;
public class Diy {
public void before(){
System.out.println("方法执行前");
}
public void after(){
System.out.println("方法执行后");
}
}
4.在applicationContext.xml中配置
配置一个切面
<!--第二种自定义-->
<bean id="diy" class="com.mahui.diy.Diy"/>
<aop:config>
<!--自定义切面-->
<aop:aspect ref="diy">
<!--切入点-->
<aop:pointcut id="pointcut" expression="execution(* com.mahui.service.UserServiceImpl.*(..))"/>
<!--切入方式-->
<aop:before method="before" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
11.3.3 aop实现方式三注解
1.抽象角色
package com.mahui.service;
public interface UserService {
public void add();
public void update();
public void select();
public void delete();
}
2.真实角色:
package com.mahui.service;
public class UserServiceImpl implements UserService {
public void add() {
System.out.println("增加了一个用户");
}
public void update() {
System.out.println("更新了一个用户");
}
public void select() {
System.out.println("查询了一个用户");
}
public void delete() {
System.out.println("删除了一个用户");
}
}
3.插入类
package com.mahui.diy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class AnnotationDiy {
@Before("execution(* com.mahui.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("方法执行前.....");
}
@After("execution(* com.mahui.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("方法执行后....");
}
@Around("execution(* com.mahui.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕前");
//继续执行
proceedingJoinPoint.proceed();
System.out.println("环绕后");
}
}
4.配置文件
<bean id="annotationdiy" class="com.mahui.diy.AnnotationDiy"/>
<!--第三种使用注解开发-->
<!--开启注解支持-->
<aop:aspectj-autoproxy/>
12整合mybatis
导入jar包:
- junit
- mysql
- mybatis
- spring相关
- aspectjweaver【aop织入包】
- mybatis-spring 【新的】
- spring-jdbc
编写配置文件
测试
12.1回忆mybatis
1.mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--mybatis核心配置文件-->
<configuration>
<!--引入配置资源-->
<properties resource="db.properties" />
<!--设置日志-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--<settings>-->
<!--<setting name="logImpl" value="LOG4J"/>-->
<!--</settings>-->
<!--起别名给实体类-->
<typeAliases>
<package name="com.mahui.pojo"/>
</typeAliases>
<!--环境配置-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper class="com.mahui.mapper.UserMapper"/>
</mappers>
</configuration>
2.pojo
package com.mahui.pojo;
public class User {
private int id;
private String name;
private String pwd;
public User() {
}
public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
3.dao
mapper
package com.mahui.mapper;
import com.mahui.pojo.User;
import java.util.List;
public interface UserMapper {
public List<User> getUser();
}
mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mahui.mapper.UserMapper">
<select id="getUser" resultType="User">
select * from mybatis.user
</select>
</mapper>
4.测试类
import com.mahui.mapper.UserMapper;
import com.mahui.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MyTest {
public static void main(String[] args) throws IOException {
String resource="mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> user = mapper.getUser();
for (User user1 : user) {
System.out.println(user1);
}
session.close();
}
}
12.2mybatis-spring
步骤:
- 编写数据源配置
- sqlSessionFactory
- sqlSessionTemplate
- 需要给接口实现类
- 将实现类注入到spring中
- 测试即可
12.2.1整合方式一
编写spring-dao.xml
SqlSessionFactoryBean//相当于mybatis中的SqlSessionFactoryBuild 用来创建sqlsessionFatory
sqlSessionTemplate //相当于mybatis中的sqlsession
spring-do.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: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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--datasource数据源-->
<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/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--引入数据源创建sqlsessionfactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--引入数据源-->
<property name="dataSource" ref="datasource"/>
<!--绑定mybatis配置文件-->
<property name="configLocation" value="mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/mahui/mapper/UserMapper.xml"/>
</bean>
<!--传入sqlsessionFactory创建sqlsessionTemplate-->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
</beans>
applicationContext.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: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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--整合配置文件-->
<import resource="spring-dao.xml"/>
<!--给具体的实现类传入sqlsessionTemplate-->
<bean id="usermapper" class="com.mahui.mapper.UserMapperImpl">
<property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>
</bean>
</beans>
mybatis-config.xml 将设置和别名留给mybatis-config
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--mybatis核心配置文件-->
<configuration>
<!--设置日志-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--起别名给实体类-->
<typeAliases>
<package name="com.mahui.pojo"/>
</typeAliases>
</configuration>
UserMapperImpl
package com.mahui.mapper;
import com.mahui.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class UserMapperImpl implements UserMapper {
private SqlSessionTemplate sqlSessionTemplate;
public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
this.sqlSessionTemplate = sqlSessionTemplate;
}
public List<User> getUser() {
UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
List<User> users = mapper.getUser();
return users;
}
}
测试:
import com.mahui.mapper.UserMapperImpl;
import com.mahui.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
import java.util.List;
public class MyTest {
public static void main(String[] args) throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapperImpl userMapper = context.getBean("usermapper", UserMapperImpl.class);
List<User> users = userMapper.getUser();
for (User user : users) {
System.out.println(user);
}
}
}
12.2.2整合方式二
spring-dao.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: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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--datasource数据源-->
<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/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--引入数据源创建sqlsessionfactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--引入数据源-->
<property name="dataSource" ref="datasource"/>
<!--绑定mybatis配置文件-->
<property name="configLocation" value="mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/mahui/mapper/UserMapper.xml"/>
</bean>
</beans>
applicationContext.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: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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--整合配置文件-->
<import resource="spring-dao.xml"/>
<!--注入实现类 引入sqlsessionfactory-->
<bean id="usermapper" class="com.mahui.mapper.UserMapperImpl2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
具体的实现类
package com.mahui.mapper;
import com.mahui.pojo.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
//继承SqlSessionDaoSupport可以拿到sqlsession
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
public List<User> getUser() {
List<User> users = getSqlSession().getMapper(UserMapper.class).getUser();
return users;
}
}
13.Spring事务管理
事务的ACID原则:
- 原子性
- 一致性
- 隔离性
- 持久性
事务的分类:
1.声明式事务:
2.编程式事务:
声明式事务
不用去改变原代码,通过配置实现事务:
spring-dao.xml 通过aop的方式将事务实现
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">
<!--datasource数据源-->
<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/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--引入数据源创建sqlsessionfactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--引入数据源-->
<property name="dataSource" ref="datasource"/>
<!--绑定mybatis配置文件-->
<property name="configLocation" value="mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/mahui/mapper/UserMapper.xml"/>
</bean>
<!--传入sqlsessionFactory创建sqlsessionTemplate-->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<!--配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="datasource" />
</bean>
<!--通过aop织入-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="addUser" propagation="REQUIRED"/>
<tx:method name="getUser" propagation="REQUIRED"/>
<tx:method name="deleteUser" propagation="REQUIRED"/>
<!--所有的-->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务的切入-->
<aop:config>
<aop:pointcut id="poincut" expression="execution(* com.mahui.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="poincut"/>
</aop:config>
</beans>