共两部分
参考
https://www.bilibili.com/video/BV1WE411d7Dv
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#spring-core
Bean作用域
he following table describes the supported scopes:
singleton
(Default) Scopes a single bean definition
to a single object instance for each Spring IoC container.
prototype
Scopes a single bean definition to any
number of object instances.
request
Scopes a single bean definition to the
lifecycle of a single HTTP request. That is, each HTTP request has its
own instance of a bean created off the back of a single bean definition.
Only valid in the context of a web-aware Spring
ApplicationContext
.
session
Scopes a single bean definition to the
lifecycle of an HTTP Session
. Only valid in the context of
a web-aware Spring ApplicationContext
.
application
Scopes a single bean definition to the
lifecycle of a ServletContext
. Only valid in the context of
a web-aware Spring ApplicationContext
.
websocket
Scopes a single bean definition to the
lifecycle of a WebSocket
. Only valid in the context of a
web-aware Spring ApplicationContext
.
1、单例模式
单例模式
2、原型模式
原型模式
3、其余 request、session、application 在 web 开发使用
Bean自动装配
1 2 3 4 5 6 7 public class People { private String name; private Dog dog; private Cat cat; 。。。 }
ByName自动装配
1 2 3 4 5 6 7 <bean id ="dog" class ="com.wnh.pojo.Dog" /> <bean id ="cat" class ="com.wnh.pojo.Cat" /> <bean id ="people" class ="com.wnh.pojo.People" autowire ="byName" > <property name ="name" value ="小杨" /> </bean >
ByType自动装配
1 2 3 4 5 6 7 <bean id ="dog2" class ="com.wnh.pojo.Dog" /> <bean id ="cat" class ="com.wnh.pojo.Cat" /> <bean id ="people" class ="com.wnh.pojo.People" autowire ="byType" > <property name ="name" value ="小杨" /> </bean >
no/constructor
注解实现自动装配
JDK1.5支持注解,Spring2.5支持注解
1 2 3 4 5 6 7 8 9 10 11 12 <?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 >
@Autowried
直接在属性前使用,也可在 set 方法上使用
使用 Autowried 就不用编写 set 方法了,前提是这个装配的属性在 IOC
容器中存在,且符合 ByName
Autowired 默认required为 true(非空,不接受空)
1 2 3 public @interface Autowired { boolean required () default true ; }
设置 false 则可空
1 @Autowired(required = false)
@Primary
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-autowired-annotation-primary
@Qualifier
限定符
1 2 3 4 5 6 7 8 public class MovieRecommender { @Autowired @Qualifier("main") private MovieCatalog movieCatalog; }
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-autowired-annotation-qualifiers
@Resource注解
1 2 3 4 5 6 7 8 9 10 public class People { private String name; @Resource(name = "dog2") private Dog dog; @Autowired private Cat cat; 。。。 }
@Resource
和@Autowried 区别:
都用来自动装配,都用在属性字段上
@Autowried 通过
ByName 的方式实现
@Resource
默认通过 ByName 的方式实现,如果找不到名字,则通过 ByType
实现,如果都找不到报错
注解开发
必须保证 aop 的包导入
使用注解需要导入 context 约束,增加注解支持
1 2 3 4 5 6 7 8 9 10 11 12 <?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 >
包扫描
1 2 <context:component-scan base-package ="com.wnh.pojo" />
属性注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Component public class User { public String name; public String getName () { return name; } @Value("老杨") public void setName (String name) { this .name = name; } }
@Component 衍生注解,根据 web
分层:
dao层注解:@Repository
service层注解:@Service
控制器层注解:@Controller
作用域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Component @Scope("prototype") public class User { public String name; public String getName () { return name; } @Value("老杨") public void setName (String name) { this .name = name; } }
xml 与注解
xml 更万能,使用任何场合,维护方便
注解维护复杂
Java 方式配置 Spring
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-java
AOP
代理模式
https://www.cnblogs.com/daniels/p/8242592.html
http://c.biancheng.net/view/1359.html
代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
代理模式的主要优点有:
代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
代理对象可以扩展目标对象的功能;
代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性
其主要缺点是:
代理模式会造成系统设计中类的数量增加
在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
增加了系统的复杂度;
静态代理
静态代理总结:
优点:可以做到在符合开闭原则的情况下对目标对象进行功能扩展。
缺点:我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。
动态代理
需要两个类:Proxy:代理,InvocationHandler:调用处理程序
接口
1 2 3 public interface BuyHouse { void buyHouse () ; }
实现类
1 2 3 4 5 6 public class BuyHouseImpl implements BuyHouse{ @Override public void buyHouse() { System.out.println("buyHouse"); } }
动态代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class DynamicProxyHandler implements InvocationHandler { private Object object; public DynamicProxyHandler (final Object object) { this .object=object; } @Override public Object invoke (Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before" ); Object result=method.invoke(object,args); System.out.println("after" ); return result; } }
测试
1 2 3 4 5 6 7 public class MyTest { public static void main (String[] args) { BuyHouse buyHouse = new BuyHouseImpl (); BuyHouse proxyBuyHouse = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(), new Class []{BuyHouse.class}, new DynamicProxyHandler (buyHouse)); proxyBuyHouse.buyHouse(); } }
AOP实现
导入依赖包
1 2 3 4 5 6 7 <dependencies > <dependency > <groupId > org.aspectj</groupId > <artifactId > aspectjweaver</artifactId > <version > 1.9.6</version > </dependency > </dependencies >
方式一
原生 Spring API接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <?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/aop https://www.springframework.org/schema/aop/spring-aop.xsd" > <bean id ="userService" class ="com.wnh.service.UserServiceImpl" /> <bean id ="beforeLog" class ="com.wnh.log.BeforeLog" /> <bean id ="afterLog" class ="com.wnh.log.AfterLog" /> <aop:config > <aop:pointcut id ="pointcut" expression ="execution(* com.wnh.service.UserServiceImpl.*(..))" /> <aop:advisor advice-ref ="beforeLog" pointcut-ref ="pointcut" /> <aop:advisor advice-ref ="afterLog" pointcut-ref ="pointcut" /> </aop:config > </beans >
UserService 接口
1 2 3 4 5 6 public interface UserService { void add () ; void delete () ; void update () ; void select () ; }
UserServiceImpl 实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class UserServiceImpl implements UserService { @Override public void add () { System.out.println("add" ); } @Override public void delete () { System.out.println("delete" ); } @Override public void update () { System.out.println("update" ); } @Override public void select () { System.out.println("select" ); } }
BeforeLog
1 2 3 4 5 6 7 8 9 10 11 12 13 public class BeforeLog implements MethodBeforeAdvice { @Override public void before (Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+"的" +method.getName()+"被执行了" ); } }
AfterLog
1 2 3 4 5 6 7 8 9 10 11 12 13 public class AfterLog implements AfterReturningAdvice { @Override public void afterReturning (Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("执行了" + method.getName()+"方法,返回值为:" +returnValue); } }
测试
1 2 3 4 5 6 @Test public void test1 () { ApplicationContext context = new ClassPathXmlApplicationContext ("applicationContext.xml" ); UserService userService = (UserService) context.getBean("userService" ); userService.add(); }
方式二
自定义类
1 2 3 4 5 6 7 8 public class DiyPointCut { public void before () { System.out.println("before" ); } public void after () { System.out.println("after" ); } }
配置
1 2 3 4 5 6 7 8 9 10 11 12 13 <bean id ="diy" class ="com.wnh.diy.DiyPointCut" /> <aop:config > <aop:aspect ref ="diy" > <aop:pointcut id ="point" expression ="execution(* com.wnh.service.UserServiceImpl.*(..))" /> <aop:before method ="before" pointcut-ref ="point" /> <aop:before method ="after" pointcut-ref ="point" /> </aop:aspect > </aop:config >
测试同上
方式三
注解
1 2 3 4 <bean id ="annotationPoint" class ="com.wnh.diy.AnnotationPoint" /> <aop:aspectj-autoproxy />
类注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 @Aspect public class AnnotationPoint { @Before("execution(* com.wnh.service.UserServiceImpl.*(..))") public void before () { System.out.println("before" ); } @After("execution(* com.wnh.service.UserServiceImpl.*(..))") public void after () { System.out.println("after" ); } @Around("execution(* com.wnh.service.UserServiceImpl.*(..))") public void around (ProceedingJoinPoint jp) throws Throwable { System.out.println("be-around" ); Signature signature = jp.getSignature(); System.out.println("signature:" +signature); Object proceed = jp.proceed(); System.out.println(proceed); System.out.println("af-around" ); } }
测试同上
整合 Mybatis
https://mybatis.org/spring/zh/index.html
Mybatis-Spring
在开始使用 MyBatis-Spring 之前,你需要先熟悉 Spring 和 MyBatis
这两个框架和有关它们的术语。这很重要——因为本手册中不会提供二者的基本内容,安装和配置教程。
MyBatis-Spring 需要以下版本:
2.0
3.5+
5.0+
4.0+
Java 8+
1.3
3.4+
3.2.2+
2.1+
Java 6+
安装
1 2 3 4 5 <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis-spring</artifactId > <version > 2.0.6</version > </dependency >
mybatis-config.xml 只留下 typeAliases 和 setting 即可
1 2 3 4 5 6 7 8 9 10 11 <?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" > <configuration > <typeAliases > <package name ="com.wnh.pojo" /> </typeAliases > </configuration >
SqlSessionTemplate
1、编写数据源
2、sqlSessionFactory
3、sqlSessionTemplate
4、接口实现类
UserMapperImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class UserMapperImpl implements UserMapper { private SqlSessionTemplate sqlSession; public void setSqlSession (SqlSessionTemplate sqlSession) { this .sqlSession = sqlSession; } @Override public List<User> selectUser () { UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.selectUser(); } }
5、将实现类注入 Spring
spring-dao.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <?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 ="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& serverTimezone=Asia/Shanghai" /> <property name ="username" value ="root" /> <property name ="password" value ="root" /> </bean > <bean id ="sqlSessionFactory" class ="org.mybatis.spring.SqlSessionFactoryBean" > <property name ="dataSource" ref ="dataSource" /> <property name ="configLocation" value ="classpath:mybatis-config.xml" /> <property name ="mapperLocations" value ="classpath:com/wnh/mapper/*.xml" /> </bean > <bean id ="sqlSession" class ="org.mybatis.spring.SqlSessionTemplate" > <constructor-arg index ="0" ref ="sqlSessionFactory" /> </bean > </beans >
applicationConext.xml
1 2 3 4 5 6 7 8 9 10 11 12 <?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" > <import resource ="spring-dao.xml" /> <bean id ="userMapper" class ="com.wnh.mapper.UserMapperImpl" > <property name ="sqlSession" ref ="sqlSession" /> </bean > </beans >
6、测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @Test public void test1 () throws IOException { String resource = "mybatis-config.xml" ; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder ().build(inputStream); SqlSession sqlSession = sessionFactory.openSession(true ); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> users = mapper.selectUser(); for (User user : users) { System.out.println(user); } } @Test public void test2 () { ApplicationContext context = new ClassPathXmlApplicationContext ("spring-dao.xml" ); UserMapper mapper = context.getBean("userMapper" ,UserMapper.class); List<User> users = mapper.selectUser(); for (User user : users) { System.out.println(user); } } @Test public void test3 () { ApplicationContext context = new ClassPathXmlApplicationContext ("applicationContext.xml" ); UserMapper mapper = context.getBean("userMapper" ,UserMapper.class); List<User> users = mapper.selectUser(); for (User user : users) { System.out.println(user); } }
SqlSessionDaoSupport
UserMapperImpl2 继承 SqlSessionDaoSupport
1 2 3 4 5 6 7 public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper { @Override public List<User> selectUser () { return getSqlSession().getMapper(UserMapper.class).selectUser(); } }
注入
1 2 3 <bean id ="userMapper2" class ="com.wnh.mapper.UserMapperImpl2" > <property name ="sqlSessionFactory" ref ="sqlSessionFactory" /> </bean >
测试
1 2 3 4 5 6 7 8 9 @Test public void test4 () { ApplicationContext context = new ClassPathXmlApplicationContext ("applicationContext.xml" ); UserMapper mapper = context.getBean("userMapper2" ,UserMapper.class); List<User> users = mapper.selectUser(); for (User user : users) { System.out.println(user); } }
事务(transaction)
标准配置
要开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个
DataSourceTransactionManager
对象:
1 2 3 <bean id ="transactionManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" > <constructor-arg ref ="dataSource" /> </bean >
共两部分