Spring Framework主要包括几个模块:

  • 支持IoC和AOP的容器;
  • 支持JDBC和ORM的数据访问模块;
  • 支持声明式事务的模块;
  • 支持基于Servlet的MVC开发;
  • 支持基于Reactive的Web开发;
  • 以及集成JMS、JavaMail、JMX、缓存等其他模块。

Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的容器(框架)!
image.png

Ioc

控制反转:IOC——Inversion of Control,指的是将对象的创建权交给 Spring 去创建。使用 Spring 之前,对象的创建都是由我们自己在代码中new创建。而使用 Spring 之后。对象的创建都是由给了 Spring 框架。

通常new一个实例,控制权由程序员控制,而”控制反转”是指new实例工作不由程序员来做而是交给Spring容器来做

IoC又称为依赖注入(DI:Dependency Injection)

  • 将组件的创建+配置与组件的使用相分离

    装配bean

通过XML文件来配置

  1. // beans.xml
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <beans xmlns="http://www.springframework.org/schema/beans"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. https://www.springframework.org/schema/beans/spring-beans.xsd">
  7. <bean id="hello" class="edu.cqupt.poio.Hello">
  8. <!--给对象中的属性设置一个值-->
  9. <property name="str" value="Spring"/>
  10. </bean>
  11. <bean id="dataSource" class="HikariDataSource" />
  12. // 把id为dataSource的组件通过属性dataSource注入到下面组件中
  13. <bean id="bookService" class="BookService">
  14. <property name="dataSource" ref="dataSource" />
  15. </bean>
  16. </beans>

总结: 在配置文件加载的时候,Spring容器中管理的对象就已经被初始化了。一旦容器初始化完毕,我们就直接从容器中获取Bean使用它们。

使用注解装配Bean

XML的写法非常繁琐,我们可以使用Annotation配置,可以完全不需要XML,让Spring自动扫描Bean并组装它们,实现自动装配

  • @Component
  • @Configuration
  • @Autowired
  • @ComponentScan
  • @Bean
  • @Qualifier
  • @Order
  1. // UserService
  2. @Component
  3. public class UserService {
  4. @Autowired
  5. MailService mailService;
  6. ...
  7. }
  8. // AppConfig
  9. @Configuration
  10. @ComponentScan
  11. public class AppConfig {
  12. public static void main(String[] args) {
  13. ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
  14. UserService userService = context.getBean(UserService.class);
  15. User user = userService.login("bob@example.com", "password");
  16. System.out.println(user.getName());
  17. }
  18. }

保证:

  • 每个Bean被标注为@Component并正确使用@Autowired注入;
  • 配置类被标注为@Configuration和@ComponentScan;
  • 所有Bean均在指定包以及子包内。

    AOP

AOP技术看上去比较神秘,但实际上,它本质就是一个动态代理,让我们把一些常用功能如权限检查、日志、事务等,从每个业务方法中剥离出来。

image.png

静态代理
动态代理

  • 动态代理的代理类是动态生成的,不是我们直接写好的,动态生成代理类

利用反射

  1. import java.lang.reflect.InvocationHandler;
  2. import java.lang.reflect.Method;
  3. import java.lang.reflect.Proxy;
  4. // 等会我们用这个类,自动生成代理类
  5. public class ProxyInVocationHandler implements InvocationHandler {
  6. private Object target;
  7. public void setTarget(Object target) {
  8. this.target = target;
  9. }
  10. public Object getProxy(){// 生成得到代理类
  11. return Proxy.newProxyInstance(this.getClass().getClassLoader(),
  12. target.getClass().getInterfaces(),this);
  13. }
  14. // 动态代理的本质,就是使用反射机制实现
  15. // 处理代理实例,并返回结果
  16. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  17. log(method.getName());
  18. Object result = method.invoke(target,args);
  19. return result;
  20. }
  21. // 给代理添加功能
  22. public void log(String msg){
  23. System.out.println("[Debug]:执行了" + msg + "方法。");
  24. }
  25. }

Spring的AOP实现就是基于JVM的动态代理。
image.png

SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:

image.png

Aop 在 不改变原有代码的情况下 , 去增加新的功能。

  • Before
  • Around
  • After

    1. @Aspect
    2. @Component
    3. public class LoggingAspect {
    4. // 在执行UserService的每个方法前执行:
    5. @Before("execution(public * com.itranswarp.learnjava.service.UserService.*(..))")
    6. public void doAccessCheck() {
    7. System.err.println("[Before] do access check...");
    8. }
    9. // 在执行MailService的每个方法前后执行:
    10. @Around("execution(public * com.itranswarp.learnjava.service.MailService.*(..))")
    11. public Object doLogging(ProceedingJoinPoint pjp) throws Throwable {
    12. System.err.println("[Around] start " + pjp.getSignature());
    13. Object retVal = pjp.proceed();
    14. System.err.println("[Around] done " + pjp.getSignature());
    15. return retVal;
    16. }
    17. }

我们使用AOP非常简单,一共需要三步:

  1. 定义执行方法,并在方法上通过AspectJ的注解告诉Spring应该在何处调用此方法;
  2. 标记@Component和@Aspect;
  3. 在@Configuration类上标注@EnableAspectJAutoProxy。

使用注解装配AOP

Mybatis-Spring

  • 编写数据源配置
  • sqlSessionFactory
  • sqlSessionTemplate
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. https://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <!--DataSource: 使用Spring的数据源替换mybatis的配置 c3p0 dbcp druid
  7. 我们使用Spring提供的jdbc-->
  8. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  9. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  10. <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
  11. <property name="username" value="root"/>
  12. <property name="password" value="123456"/>
  13. </bean>
  14. <!--SqlSessionFactory-->
  15. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  16. <property name="dataSource" ref="dataSource" />
  17. <!--绑定Mybatis配置文件-->
  18. <property name="configLocation" value="classpath:mybatis-config.xml"/>
  19. <property name="mapperLocations" value="classpath:edu/cqupt/mapper/*.xml"/>
  20. </bean>
  21. <!--SqlSessionTemplate 就是我们使用的的SqlSession-->
  22. <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
  23. <!--只能使用构造器注入SqlSessionFactory 因为他没有set方法-->
  24. <constructor-arg index="0" ref="sqlSessionFactory"/>
  25. </bean>
  26. </beans>

或者,使用 sqlSessionFactory

  1. <bean id="userMapper" class="edu.cqupt.mapper.UserMapperImpl">
  2. <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
  3. </bean>
  4. // 1 继承 SqlSessionDaoSupport
  5. // 2 使用getSqlSession()方法获得SqlSession
  6. public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
  7. public List<User> selectUser() {
  8. UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
  9. return mapper.selectUser();
  10. }
  11. }