Spring IOC AOP相关知识

Spring

  • Spring主要解决的问题
      • IoC容器
      • 基础服务
      • 功能
  • IOC 控制反转
    • 配置方法
      • xml配置:
        • 1.属性配置:
        • 2.bean的实例化
        • 3.Spring的FactoryBean接口实例化
        • 4.依赖注入
        • 5. bean的作用域
        • 6. bean的生命周期
        • 7.优势
      • 注解式配置:
      • java式配置:
  • AOP
      • 应用场景
      • xml配置
      • 注释式配置
      • java式配置
  • 代理模式
        • 静态代理

Spring主要解决的问题

简单来说,就是处理对象的创建、以及对象的依赖关系
核心理念: IOC inversion of control 控制反转 / DI dependency injection 依赖注入

IoC容器

spring-beans : ioc 实现,配置文件的访问、创建和管理

spring-core: 核心工具包

spring-context:封装IOC容器,提供扩展功能

SpEL : spring的表达式支持

基础服务

AOP : 面向切面编程支持

Aspects: 对AspectJ框架的支持

instrumentation: 字节码操作

messaging : 对消息服务的支持

功能

transactions : 事务支持

JDBC : spring对JDBC的封装

ORM : spring对于ORM框架的支持

web : 对于web开发的支持
Spring IOC AOP相关知识_第1张图片

IOC 控制反转

控制权从调用的类转换到Spring容器,由Spring来实例化对象依赖注入

  1. 创建对象
  2. 依赖注入 (为属性填入实例);

配置方法

xml配置:

1.属性配置:

//声明一个普通bean
<bean id="userDao" class="com.woniuxy.spring.dao.daoimp.UserDaoImp"/>
    <bean id="userService" class="com.woniuxy.spring.service.serviceimp.UserServiceImp">
    	//ref 注入已有的bean
        <property name="userDao" ref="userDao"/>
        //value 注入基本类型
        <property name="age" value="20"/>
        //注入list
        <property name="list">
            <list>
                <value>1value>
                <value>2value>
                <value>3value>
                <value>4value>
            list>
        property>
        //注入map
        <property name="map">
            <map>
                <entry key="pig" value="pick">entry>
                <entry key="dog" value="yellow">entry>
                <entry key="cat" value="black">entry>
            map>
        property>
    bean>
beans>

2.bean的实例化

//默认构造器实例化
<bean id="userDao" class="com.woniuxy.spring.dao.daoimp.UserDaoImp"/>

//静态工厂方法实例化

<bean id="connection" factory-method="getConnection" class="com.woniuxy.spring.common.JDBCUtils"/>

     
//工厂bean实例化
<bean id="holidayFactory" class="com.woniuxy.spring.factory.HolidayFactory"/>
<bean id="holiday" factory-bean="holidayFactory" factory-method="create">bean>

3.Spring的FactoryBean接口实例化

一个类实现FactoryBean接口,实现其方法
配置之后,bean的实例为FactoryBean#getObject方法的返回值
java类:

 public class CarFactory implements FactoryBean<Car> {
       
           @Override
           public Car getObject() throws Exception {
               return new Car();
           }
       
           @Override
           public Class<?> getObjectType() {
               return Car.class;
           }
       }

xml配置:

<bean id="car" class="com.woniuxy.spring.factory.CarFactory"/>

4.依赖注入

setter注入:

<bean id="userService" class="com.woniuxy.spring.service.serviceimp.UserServiceImp">
   <property name="userDao" ref="userDao"/>
bean>
public class UserServiceImp implements UserService {
   //属性
   private UserDaoImp tdi;
   //setter注入
   public void setTdi(UserDaoImp tdi) {
   	this.tdi = tdi;
   }
}

构造器注入:

<bean id="userDao" class="com.woniuxy.spring.dao.daoimp.UserDaoImp"/>
<bean id="userService" class="com.woniuxy.spring.service.serviceimp.UserServiceImp">
   <constructor-arg  name="tdi" ref="userDao"/>
   <constructor-arg  index="1" value="20"/>
bean>
public class UserServiceImp implements UserService {
   //属性
   private UserDaoImp tdi;
   private String age;
   //构造器注入
   public UserServiceImp(UserDaoImp tdi,String age){
   	this.tdi = tdi;
   	this.age = age;
   }
}

5. bean的作用域

<bean id="userDao" class="com.woniuxy.spring.dao.daoimp.UserDaoImp"/>
<bean id="userService" class="com.woniuxy.spring.service.serviceimp.UserServiceImp">
   <constructor-arg  name="tdi" ref="userDao"/>
   <constructor-arg  index="1" value="20"/>
bean>

prototype 原型 => 每次创建一个实例
[*]singleton 单例 => 一个bean的定义,只有一个实例,不是一个类只有一个实例(默认为单例)
request 一个请求一个实例
session 一个会话一个实例
websocket 一次websocket链接一个实例

6. bean的生命周期

1.在bean配置上写init-method和destroy-method
2.实现InitializingBean和DisposableBean及其方法

public class Cycle2 implements InitializingBean, DisposableBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("开始....");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("结束了....");
    }
}
     

7.优势

解耦合,类与类之间的耦合度降低;
提升代码的灵活性,可维护性

注解式配置:

注解
注册springbean @Controller @Service @Repository @Component
自动依赖注入 @Autowired @Value
生命周期 @PostConstruct @PreDestroy
作用域范围 @Scope

xml配置

  
  <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 https://www.springframework.org/schema/context/spring-context.xsd">
  
      
      <context:component-scan base-package="com.woniuxy.spring"/>
  
  beans>

java式配置:

注解@Bean @Configuration @ComponentScan

@Configuration 标记一个类为配置类
@Bean 标记某个方法返回值为spring的bean,方法参数为依赖注入的请求

扫描

@Configuration 标记一个类为配置类 applicationContext.xml

@ComponentScan 打开包扫描功能,并且指定扫描的包 等价于

加入@Controller...@Autowired

@PropertySource("{配置文件位置}")

java配置

@Configuration
@ComponentScan("com.woniuxy.spring")
@PropertySource("database.properties")
public class AppConfig {
	//获取配置文件database.properties里的信息
    @Value("${forname}")
    private String forname;
    @Value("${url}")
    private String url;
    @Value("${user}")
    private String user;
    @Value("${password}")
    private String password;
    //配置Bean
    @Bean
    public UserDaoImp userDaoImp(){
        return new UserDaoImp();
    }
    @Bean
    public UserServiceImp userServiceImp(){
        return new UserServiceImp();
    }
    //结束时调用关闭的方法
    @Bean(destroyMethod = "close")
    public DruidDataSource druidDataSource(){
        DruidDataSource dds = new DruidDataSource();
        dds.setDriverClassName(forname);
        dds.setUrl(url);
        dds.setUsername(user);
        dds.setPassword(password);
        return dds;
    }
}   
public static void main(String[] args) throws SQLException {
	//读取java配置
    ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
    //读取Bean,获得实体类
    UserServiceImp usi = ac.getBean("userServiceImp",UserServiceImp.class);
}

AOP

AOP Aspect Oritented Programming 面向切面编程
连接点 JoinPoint 需要加入功能的位置,方法
切入点 PointCut 真正执行加入功能的连接点
通知 Advice 需要实现的功能,实现MethodBeforeAdivce接口
前置通知 : 方法执行之前 MethodBeforeAdvice
后置通知 : 方法执行之后 AfterReturningAdvice
环绕通知 : 方法执行前后 MethodInterceptor
异常通知 : 抛出异常时
最终通知 : finally
切面 Aspect Java语言中,将切入点和通知等组装在一起的代码单元
目标对象 Target 要操作的对象
织入 Weave 将功能加入到切入点中的过程
事务 : 一批同时成功或失败的DML

应用场景

打印日志、性能监控、事务管理、安全验证,每一个类的每一个public方法的参数都打印出来…

xml配置

1.配置service
2.配置通知
3.配置切入点,class= org.springframework.aop.support.JdkRegexpMethodPointcut 4.配置属性pattern=> service的方法
5.配置切面,class=org.springframework.aop.support.DefaultPointcutAdvisor 连接切入点和通知
6.包装service类, class= org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator
7.获取bean,调用方法,将会看到通知执行了


<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="userService" class="com.woniuxy.spring.service.serviceimp.UserServiceImp"/>
    
    <bean id="beforeExecution" class="com.woniuxy.spring.component.Before"/>

    
    <bean id="pointCut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
        <property name="pattern" value="com.woniuxy.spring.service.serviceimp.UserServiceImp.addUser"/>
    bean>

    
    <bean id="aspect" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <property name="pointcut" ref="pointCut"/>
        <property name="advice" ref="test"/>
    bean>

    
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">

    bean>

    <bean id="test" class="com.woniuxy.spring.component.Test"/>
beans>

注释式配置

xml配置


<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 http://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.woniuxy.spring.service.serviceimp.UserServiceImp"/>
    
    <bean id="txAdvice" class="com.woniuxy.spring.component.Test1"/>
    <aop:config>
        <aop:aspect ref="txAdvice">
            <aop:pointcut id="servicePointcut" expression="execution(* com.woniuxy.spring.service.serviceimp.UserServiceImp.*(..))"/>
            <aop:before method="begin" pointcut-ref="servicePointcut"/>
            <aop:after-returning method="commit" pointcut-ref="servicePointcut"/>
            <aop:after-throwing method="rollback" pointcut-ref="servicePointcut"/>
        aop:aspect>
    aop:config>
beans>

java注解

@Configuration
@ComponentScan("com.woniuxy.spring")
@EnableAspectJAutoProxy
public class TXconfig {
    
}

java式配置

@Component
@Aspect
public class TXApsect {
    @Pointcut("execution(* com.woniuxy.spring.service.serviceimp.UserServiceImp.*(..))")
    public void servicePointcut(){}

    @Around("servicePointcut()")
    public Object invoke(ProceedingJoinPoint pjp) {
        Object[] args = pjp.getArgs();
        Object result = null;
        try {
            System.out.println("开启事务");
            result = pjp.proceed(args);
            System.out.println("提交事务");
        }catch (Throwable t){
            t.printStackTrace();
            System.out.println("回滚事务");
        }
        return result;
    }
}

代理模式

静态代理

1.代理类和被代理类必须有相同的接口
2.代理类持有了被代理类对象
一个有趣的代理模式代码:
接口

public interface Invest {
    double invoke(double money);
}

Boss类

public class Boss implements Invest{
    public double invoke(double money) {
        System.out.println("老板:"+money+"万,已经打在卡上了,你看到没有");
        return money;
    }
}

Proxy类

public class Proxy implements Invest{
    Boss boss = new Boss();
    public Proxy(Boss boss){
        this.boss = boss;
    }
    public double invoke(double money) {
        double newMoney = money *1.2;
        System.out.println("代理:客户需要"+money+"万,我给老板说需要"+newMoney+"万,自己扣下"+(money*0.2)+"万");
        double bossMoney = boss.invoke(newMoney);
        return money;
    }
}

Subject类

public class Subject {
    public static void main(String[] args) {
        Boss boss = new Boss();
        Invest in = new Proxy(boss);
        System.out.println("客户:我需要1000.0万");
        double money = in.invoke(1000);
        System.out.println("客户:已经收到了"+money+"万");
    }
}

你可能感兴趣的:(Spring IOC AOP相关知识)