Spring配置
github上下载源码zip
在maven里导包 spring-mvc
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.32</version>
</dependency>
IOC 控制反转
AOP 面向切面编程
spring必须要有set方法,只有这样才能实现控制反转。
核心配置文件
<?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="..." class="...">
<!-- 这个bean的合作者和配置在这里 -->
</bean>
<bean id="..." class="...">
<!-- c这个bean的合作者和配置在这里 -->
</bean>
<!-- 更多bean 定义在这里 -->
bean就是spring里的对象,对象不用new了,通过spring创建。
配置
bean配置
import:
在一个配置文件里导入其他配置文件,以此合并为一个
别名
依赖注入
1.构造器注入
需要有构造函数
2.set注入
需要有set方法!
3.拓展方式注入
各种注入方式
(同一个id的注入要写在一个里面,不可以分开写)
<bean id="student" class="com.li.pojo.Student">
<!-- 普通值注入-->
<property name="name" value="小李"/>
<!-- bena注入-->
<property name="address" ref="address"/>
<!-- 数组注入-->
<property name="books">
<array>
<value>三国演义</value>
<value>水浒传</value>
<value>红楼梦</value>
<value>西游记</value>
</array>
</property>
<!-- List注入-->
<property name="hobbies">
<list>
<value>唱</value>
<value>跳</value>
<value>rap</value>
</list>
</property>
<!-- map注入-->
<property name="card" >
<map>
<entry value="1" key="2"/>
</map>
</property>
<!-- set注入-->
<property name="games">
<value>sada</value>
</property>
<!-- null注入-->
<property name="wife" value=""/>
<!-- properties注入-->
<property name="info">
<props>
<prop key="1">13</prop>
</props>
</property>
</bean>
p命名和c命名
p命名可以直接注入属性的值
p配置导入
xmlns:p="http://www.springframework.org/schema/p"
编写规范
<bean id="user" class="com.li.pojo.User" p:name="小李" p:age="18"/>
c命名,类似于有参构造器注入
c配置导入
xmlns:c="http://www.springframework.org/schema/c"
编写规范
<bean id="user2" class="com.li.pojo.User" c:name="小李" c:age="18"/>
设计模式
单例模式:所有对象指的都是同一个(spring默认模式)
原型模式:每个对象都是独立的
......
自动装配
auto wire
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid;
byType:对象属性相同的bean
使用注解实现自动装配
1.导入约束(配置注解支持)
<?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>
@Autowired:
直接在属性上使用即可,也可以在set方式上使用
使用Autowired 我们可以不用编写Set方法了,前提是配置正确,且名字一样,实际上还是根据byType,但可以不用set方法了。
@Qualifier,
指定装配
前面两个是配套的spring的注解
@resource
是java注解,不推荐
@Nullable
该字段可以为空
使用注解开发
1.导入aop,xml里需要有注解支持
@Component 主键,等价于在xml注册一个bean
@Value,给属性赋值
和Component一样的注解如下,只是不同层习惯用不同注解
dao @Repository
service @Service
controller @Controller
@Scope
代理模式
静态代理
有一个代理类(自己生成)
不改变原先代码,而是增加一个代理对象,那就不会对原先代码产生影响,属于解耦过程
不改变原先代码,就实现要增加功能的目标
动态代理(代理的是一个接口)
角色和静态代理一样
代理类是动态生成的,不是直接写好
两大类:基于接口(JDK),基于类(cglib),java字节码(Javasist)
基于接口
工具类(万能的):
package com.li.demo02;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//用于动态创建代理对象
public class CreateProxy 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);
}
//对产生的这个类进行加工,要是不加工就是返回一个和真实对象一样的代理对象
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(target,args);
return result;
}
}
实现的过程
package com.li.demo02;
public class Client {
public static void main(String[] args) {
UserServiceImp01 userServiceImp01 = new UserServiceImp01();//必须有一个真实对象
CreateProxy proxy = new CreateProxy();
proxy.setTarget(userServiceImp01);//放入真实对象以获取代理
UserService01 proxy1 = (UserService01) proxy.getProxy();
proxy1.add();
}
}
AOP
底层就是动态代理
AOP 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">
<!-- bean definitions here -->
导入依赖
除了aop还要导入这个依赖
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.22</version>
<scope>runtime</scope>
</dependency>
方法一:使用Spring的API接口(通过类实现接口)
aop的配置切点和执行环绕
<aop:config>
<!-- 切入点-->
<aop:pointcut id="pointcut" expression="execution(* com.li.pojo.UserServiceImp.*(..))"/>
<!--执行环绕-->
<aop:advisor advice-ref="add" pointcut-ref="pointcut"/>
</aop:config>
方法二:自定义类(切面) 简单一点(通过xml里的切面配置)
<bean id="prase" class="com.li.dao.Prase"/>
<aop:config>
<aop:aspect ref="prase">
<aop:pointcut id="pointcut" expression="execution(* com.li.pojo.UserServiceImp.*(..))"/>
<aop:before method="before" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
方式三:注解实现
需要导入aspectj依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
在xml里开启自动aop
<aop:aspectj-autoproxy/>
直接在类里实现
package com.li.dao;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class Test01 {
@Before(value = "execution(* com.li.pojo.UserServiceImp.*(..))")
public void before()
{
System.out.println("执行前");
}
@After(value = "execution(* com.li.pojo.UserServiceImp.*(..))")
public void after()
{
System.out.println("执行后");
}
}
整合Mybatis
https://mp.weixin.qq.com/s/gXFMNU83_7PqTkNZUgvigA
导入依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<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>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
</dependencies>
beans.xml的配置
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?useSSl=true&useUnicode=true&characterEncoding=UTF-8"/>
<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/li/mapper/UserMapper.xml"/>
</bean>
<!--注册sqlSessionTemplate , 关联sqlSessionFactory-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--利用构造器注入-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<bean id="userDao" class="com.li.mapper.UserDaoImp">
<property name="sqlSession" ref="sqlSession"/>
</bean>
实现类的编写
package com.li.mapper;
import com.li.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class UserDaoImp implements UserMapper {
//sqlSession不用我们自己创建了,Spring来管理
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> getUsers() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.getUsers();
}
}
声明性事务
事物的ACID原则:原子性,一致性,隔离性,持久性
声明性事务:AOP
事务xml配置以及aop织入
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice transaction-manager="transactionManager" id="interceptor">
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="select" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.li.Dao.*.*(..))"/>
<aop:advisor advice-ref="interceptor" pointcut-ref="pointcut"/>
</aop:config>
编程式事务:会影响原来的代码
不推荐,不用
Leave a reply