SSM框架

spring核心容器

容器

bean

依赖注入

IOC控制反转

使用对象:从主动new对象变成了外部提供,由IOC容器(外部)负责管理对象,被管理的对象叫做Bean。

DI:依赖注入,绑定两个对象之间的关系。

bean创建出来默认是单例模式,因此封装的model对象其实是不适合交给容器管理的。

实例化bean的三种方式

  1. 通过构造方式(反射)

  2. 静态工厂(了解即可

  3. 实例化工厂

  4. (重)FactoryBean接口

  5. public class UserDaoFactory implements FactoryBean<UserDao> {
    
        @Override
        public UserDao getObject() throws Exception {
            return new UserDaoImpl();
        }
    
        @Override
        public Class<?> getObjectType() {
            return UserDao.class;
        }
    }
    
    
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41



    ### 依赖注入的方式

    1. setter注入
    2. 构造器注入
    3. 自动装配(自动找寻set入口装配,所以set入口不能省略
    - 按类型
    - 按名称(不需要

    自动装配的优先级要小于setter和构造器

    ### 核心容器总结

    #### 容器相关

    BeanFactory是IOC容器的顶层接口,是bean的延迟加载

    ApplicationContext是ioc的核心接口,是bean的立即加载

    ![image-20241114210710832](C:\Users\86158\AppData\Roaming\Typora\typora-user-images\image-20241114210710832.png)

    ![image-20241114210845222](C:\Users\86158\AppData\Roaming\Typora\typora-user-images\image-20241114210845222.png)

    ## 注解开发

    ```java
    //创建新的命名空间context,需要包扫描
    <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">
    <!-- 1.先创建命名空间context-->
    <!-- 注解开发-->
    <!-- 扫描组件配置-->
    <context:component-scan base-package="org.demo"/>
1
2
3
4
5
6
7
8
9
@Component("userDao")
//相当于
<bean id="userDao" class="org.demo.dao.impl.UserDaoImpl"/>
//交给容器管理

// 按名称获取bean
BookDao bookDao = (BookDao) context.getBean("bookDao");
bookDao.save();

按名称注入不推荐

1
2
3
4
5
@Component
//不另命名
BookService bookService = context.getBean(BookService.class);
//按类型获取bean
System.out.println(bookService);

不过表现层用@Controller,业务层@Service,数据层@Repository,只是便于区分,功能和component一样的

配置类

1
2
3
@Configuration //配置类
@ComponentSpan({"org.demo","com.example"})//包扫描
//完全取代applicationContext.xml这个配置文件了

注解注入

1
2
@Autowired
@Qualifier("命名")//这个是给一个接口有两个实现类时,选择其中一个命名来的

AOP面向切面编程

在不惊动原始设计的基础上,为其增强功能的编程思想。

image-20241114222040947

将切入点和通知绑定的东西,叫做切面

想要增强的共性功能,叫做通知

通知类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Component
@Aspect //告诉扫描我是aop
public class MyNotice {
//定义切入点
@Pointcut("execution(void org.demo.dao.BookDao.delete())")
private void pt(){};

//定义通知,并切面:绑定通知和切入点关系
@Before("pt()")
public void method(){
System.out.println("method");
System.out.println(System.currentTimeMillis());
}
}
1
2
3
4
5
@Configuration
@ComponentScan("org.demo")
@EnableAspectJAutoProxy //扫描切面的注解
public class SpringConfig {
}
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
32
33
34
35
36
37
38
39
//5个切面类型
@Component
@Aspect
public class MyAdvice {
//定义切入点
@Pointcut("execution(* org.demo.dao.BookDao.*(..))")
private void pt(){};

//定义通知,并切面:绑定通知和切入点关系
//1.前置通知
@Before("pt()")
public void before(){
System.out.println("method");
System.out.println(System.currentTimeMillis());
}
//2.环绕通知
@Around("pt()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("around start");
joinPoint.proceed();
System.out.println("around end");
}
//3.后置通知(无论通知运行出不出错都执行
@After("pt()")
public void after(){
System.out.println("after ");
}
//4.不出错后置执行
@AfterReturning("pt()")
public void afterReturning(){
System.out.println("afterReturning ");
}
//5.出错异常后执行
@AfterThrowing("pt()")
public void afterThrowing(){
System.out.println("afterThrowing ");
}
}

假如有多个MyAdvice可以通过

1
2
@Order(1)

来着控制切面类的执行顺序

切入点表达式

1
("execution(* org.demo.dao.BookDao.*(..))")
1
2
("@annotation(包名.自定义注解)")
//有该注解的方法生效