一、Spring简介
Spring是由Rod Jahnson在2004年推出的框架,
早在2002年就有了Spring的前身interface21,也是由Rod Jahson发表的。
Spring的初衷就是使JAVA EE开发应该更加简单,它在一定程度上可以看作为一个容器。
官网:https://spring.io
Spring的优点:
- 简化了java企业级应用的开发
- Spring是免费开源的框架
- Spring是轻量级的,非入侵式的框架
- 控制反转(IOC),面向切面(AOP)特性
- 容易整合其他的框架,支持事务等
Spring核心模块:
Spring为开发者提供了七大核心模块
1、核心容器(Core)
Spring框架中最基础的部分,它通过依赖注入(DI)来实现容器对Bean的管理。BeanFactory是工厂模式的一个实现,它使用IoC将应用配置和依赖说明从实际的应用代码中分离出来,也是是任何Spring应用的核心。
2、应用上下文(Context)
核心模块的BeanFactory使Spring成为一个容器,而上下文模块使它成为一个框架。这个模块扩展了BeanFactory的概念,增加了对国际化(I18N)消息、事件传播以及验证的支持。
3、Spring的AOP模块
Spring在它的AOP模块中提供了对面向切面编程的丰富支持。这个模块是在Spring应用中实现切面编程的基础。Spring的AOP模块也将元数据编程引入了Spring。可以通过AOP面向切面编程,在不改变原来代码的情况下对旧方法和功能的增强。
4、JDBC抽象和DAO模块
Spring的JDBC和DAO模块抽取了原生JDBC重复的代码,可以保持你的数据库访问代码干净简洁,并且可以防止因关闭数据库资源失败而引起的问题。这个模块给出的错误消息上面建立了一个有意义的异常层。这个模块还使用了Spring的AOP模块为Spring应用中的对象提供了事务管理服务。
5、对象/关系映射集成模块
Spring提供了ORM模块。Spring为几ORM框架提供了集成方案,包括Hibernate、JDO和iBATIS SQL映射。Spring的事务管理支持这些ORM框架中的每一个也包括JDBC。
6、Spring的Web模块
Web上下文模块建立于应用上下文模块之上,提供了一个适合于Web应用的上下文。另外,这个模块还提供了一些面向服务支持。也提供了Spring和其它Web框架的集成,比如Struts等。
7、Spring的Mvc框架
Spring为构建Web应用提供了一个功能全面的MVC框架。虽然Spring可以很容易地与其它MVC框架集成,例如Struts,但Spring的MVC框架使用IoC对控制逻辑和业务对象提供了完全的分离。
二、控制反转(IOC)
控制反转是一种通过描述(XML或注解)并通过第三方去产生或获取对象的方式。
以前编程,由程序员自己声明对象,有了IOC,可以将对象托管到第三方容器中,从容器中获取依赖。
在Spring中实现控制反转的是IOC容器。其实现方法是依赖注入(DI)。
创建步骤:
1、maven中导入依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!--junit包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
2、创建实体类
public class User {
private String name;
public void show(){
System.out.println("IOC Study");
}
}
3、创建spring的配置文件bean1.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">
<bean id="hello" class="com.llj.pojo.User"/>
</beans>
4、单元测试
@Test
public void test(){
//解析beans.xml配置文件,生成管理Bean对象的容器context
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
User user = (User) context.getBean("hello");
user.show();
}
Spring先从xml文件或者注解配置类中获取注入的对象和参数,然后程序员再从容器中获取对应的值。
XML配置方法
1、无参构造:
<bean id="user" class="com.llj.pojo.User"/>
2、有参构造:
<!--根据构造器参数下标-->
<bean id="user1" class="com.llj.pojo.User">
<constructor-arg index="0" value="张三"/>
</bean>
<!--根据构造器类型-->
<bean id="user2" class="com.llj.pojo.User">
<constructor-arg type="java.lang.String" value="李四"/>
</bean>
<!--根据构造器参数名称-->
<bean id="user3" class="com.llj.pojo.User">
<constructor-arg name="name" value="张三"/>
</bean>
3、set方法
<!-- 2、 通过set方法注入属性 -->
<bean id="book1" class="com.llj.User">
<!-- 使用property完成属性的注入
name:类里面属性名称
value:向属性赋值
-->
<property name="name" value="曹贼"></property>
</bean>
4、通过p标签进行注入
在beans标签中添加: xmlns:p="http://www.springframework.org/schema/p"
<!-- 4、 通过p空间set注入属性 -->
<bean id="book1" class="com.llj.User" p:name="刘皇叔">
</bean>
三、依赖注入:
1、内部bean 手动装配
<bean id="empt" class="com.llj.dept.Empt">
<property name="ename" value="张三"></property>
<property name="gender" value="男"></property>
<property name="dept">
<bean id="dept" class="com.llj.dept.Dept">
<property name="dname" value="安保部"></property>
</bean>
</property>
</bean>
2、级联bean
<bean id="empt" class="com.llj.dept.Empt">
<property name="ename" value="huahua"></property>
<property name="gender" value="女"></property>
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.llj.dept.Dept">
<property name="dname" value="技术部"></property>
</bean>
3、各种数据结构进行属性注入(String,list,map,set)
<bean id="stu" class="com.llj1.stu">
<!--String注入-->
<property name="strings">
<array>
<value>星期1</value>
<value>星期2</value>
<value>星期3</value>
</array>
</property>
<!--list注入-->
<property name="lists">
<list>
<value>一月</value>
<value>二月</value>
<value>三月</value>
<value>四月</value>
</list>
</property>
<!--map注入-->
<property name="maps">
<map>
<entry key="小猫" value="喵喵"></entry>
<entry key="小狗" value="汪汪"></entry>
<entry key="小猪" value="哼哼"></entry>
</map>
</property>
<!--set注入-->
<property name="sets">
<set>
<value>加顿男爵</value>
<value>黑色玫瑰</value>
</set>
</property>
<!--null注入-->
<property name="wife">
<null/>
</property>
</bean>
四、 autowire 自动装配:
<bean id="emp" class="com.autowire.Emp" autowire="byName"></bean>
<bean id="dept" class="com.autowire.Dept"></bean>
autowire=“byName” 流程
1.会先找User类的所有set方法
2.set方法名去掉set,首字母小写就是自动装配名字
3.去配置文件中的bean中找有没有相同的名字
4.有就自动装配,没有可能会报错
autowire=“byType” 是根据类型进行装配的,类型必须唯一,不唯一会报NoUniqueBeanDefinitionException错
用注解自动装配:
第一步:在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
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
第二步:导入注解配置
<context:annotation-config/>
第三步:在实体类中加入注解
public class User {
@Autowired(required = false)
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
private Dog dog;
private String str;
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;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
@Autowired注解
@Autowired 注释是一个用于容器 ( container ) 配置的注释。
按类型进行匹配,required=false表示可以为空 ,
相似作用的注解有 :@Required @Primary @Qualifier ,但是@Qualifier不能单独使用,需要前面加上@Autwired
五、注解开发
步骤:
①在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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解-->
<context:annotation-config/>
<!--扫描com.llj包下的注解-->
<context:component-scan base-package="com.llj"/>
</beans>
②创建实体类配置注解
@Component("user")
@Scope("singleton")
//相当于<bean id="user" class=""/>
public class User {
@Value("1")
private int id;
@Value("张三")
//<property name="name" value="张三"/>
private String name;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
③测试
public class MyTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
User bean = (User) context.getBean("user");
System.out.println(bean);
}
}
@Component注解
表示配置一个bean
三层架构的三个衍生注解:
Dao层:@Reposity
Service层 : @Service
Controller层 : @Controller
@Autowire注解
自动装配属性,搭配@Qualifier可以根据名字进行自动装配
@Nullable 可以为空
@Scope注解(作用域)
- singleton:单例模式
- prototype:多例模式
注解配置
注解配置可代替xml配置文件,但是一般可以两者一起用。
注解配置可以方便注入我们自己写的类,xml文件可以导入其他资源,两者各有优势
新建Config包,包下建注解类
@Configuration //代表这是一个配置类
@Import(MyConfig2.class) //用于合并其他配置类
public class MyConfig {
@Bean //通过方法注册一个bean,这里的返回值就Bean的类型,方法名就是bean的id!
public Dog dog(){
return new Dog();
}
}
AOP面向切面
理解:AOP(Aspect Oriented Programming)面向切面编程,通过预编译和运行期动态代理实现程序功能的统一维护的种技术。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分的耦合度降低,提高程序的可重用性,提高了开发效率。
AOP中的名词
横切关注点:跨越应用程序多个模块的方法或功能。如日志 , 安全 , 缓存 , 事务等等 …
切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
目标(Target):被通知对象。
代理(Proxy):向目标对象应用通知之后创建的对象。
切入点(PointCut):切面通知 执行的 “地点”的定义。
连接点(JointPoint):与切入点匹配的执行点。
使用AOP步骤
1、导入maven中的相关包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
2、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"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启组件扫描-->
<context:component-scan base-package="com.Anno"></context:component-scan>
<!--开启aspectj-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
3、创建代理类和被代理类
被代理类
@Component
public class pojo {
public void eat(){
System.out.println("吃饭");
}
}
代理类
@Component
@Aspect
@Order(1)
public class pojoProxy {
@Before(value = "execution(* rewiew.pojo.eat(..))")
public void pBefore(){
System.out.println("洗手");
}
}
4、测试
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
pojo pojo1 = (pojo) context.getBean("pojo");
pojo1.eat();
}
注解配置AOP的几个通知方式
@Before
前置通知,在连接点方法前调用
@Around
环绕通知,它将覆盖原有方法,但是允许你通过反射调用原有方法,后面会讲
@After
后置通知,在连接点方法后调用
@AfterReturning
返回通知,在连接点方法执行并正常返回后调用,要求连接点方法在执行过程中没有发生异常
@AfterThrowing
异常通知,当连接点方法异常时调用
Spring整合MyBatis
第一步:导入核心包
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!--数据库连接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--spring相关的-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.10.RELEASE</version>
</dependency>
<!--aop织入-->
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!--mybatis-spring整合包 【重点】-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
第二步配置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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置数据源-->
<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=true&useUnicode=true&characterEncoding=utf8"/>
<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="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/kuang/dao/*.xml"/>
</bean>
<!--注册sqlSessionTemplate , 关联sqlSessionFactory-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--利用构造器注入-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
</beans>
第三步:配置dao --> Mapper
public class UserDaoImpl implements UserMapper {
//sqlSession不用我们自己创建了,Spring来管理
@Autowird
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
public List<User> selectUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
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"
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
http://www.springframework.org/schema/tx/spring-tx.xsd">
<import resource="spring-dao.xml"/>
<bean id="userMapper" class="com.yang.mapper.UserMapperImpl2">
<property name="sqlSessionTemplate" ref="sqlSession"/>
</bean>
<!--配置声明事务注入-->
<!--要开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个 DataSourceTransactionManager 对象:-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
<!--或者使用构造注入-->
<!--<constructor-arg ref="dataSource" />-->
</bean>
<!--结合AOP实现事务的织入-->
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--给哪些方法配置事务-->
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="select" read-only="true"/>
<!--全部方法-->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<!--该包下的所有方法-->
<aop:pointcut id="txPointCut" expression="execution(* com.yang.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
</beans>
配置事务的传播特性 propagation
PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。
PROPAGATION_SUPPORTS:支持当前事务,如果没有当前事务,就以非事务方法执行。
PROPAGATION_MANDATORY:使用当前事务,如果没有当前事务,就抛出异常。
PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER:以非事务方式执行操作,如果当前事务存在则抛出异常。
PROPAGATION_NESTED: 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED 类似的操作
下阶段整理mybatis学习笔记 ,谢谢观看😊