Spring-IOC

Posted 星辰大海

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring-IOC相关的知识,希望对你有一定的参考价值。

结构:

HelloWorld.java:

package com.spring.test.helloWorld;

public interface HelloWorld {
    
    public void sayHello();
     
}

HelloWorldService.java:

package com.spring.test.helloWorld;

public class HelloWorldService {
      
    private HelloWorld helloWorld;
  
    public HelloWorldService() {
  
    }
  
    public void setHelloWorld(HelloWorld helloWorld) {
        this.helloWorld = helloWorld;
    }
  
    public HelloWorld getHelloWorld() {
        return this.helloWorld;
    }
  
}

SpringHelloWorld.java:

package com.spring.test.helloWorld.impl;

import com.spring.test.helloWorld.HelloWorld;

public class SpringHelloWorld implements HelloWorld {
      
    @Override
    public void sayHello() {
        System.out.println("Spring Say Hello!!");
    }
  
}

StrutsHelloWorld.java:

package com.spring.test.helloWorld.impl;

import com.spring.test.helloWorld.HelloWorld;

public class StrutsHelloWorld implements HelloWorld {
      
    @Override
    public void sayHello() {
        System.out.println("Struts Say Hello!!");
    }
  
}

beans.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd">
  
    <bean id="springHelloWorld"
        class="com.spring.test.helloWorld.impl.SpringHelloWorld"></bean>
    <bean id="strutsHelloWorld"
        class="com.spring.test.helloWorld.impl.StrutsHelloWorld"></bean>
  
    <bean id="helloWorldService"
        class="com.spring.test.helloWorld.HelloWorldService">
        <property name="helloWorld" ref="springHelloWorld"/>
    </bean>
  
</beans>

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.spring</groupId>
  <artifactId>Spring</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
 
        <!-- Spring Core -->
        <!-- http://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>
         
        <!-- Spring Context -->
        <!-- http://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>
  </dependencies>
</project>

HelloProgram.java:

package com.spring.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.test.helloWorld.HelloWorld;
import com.spring.test.helloWorld.HelloWorldService;
public class HelloProgram {
    public static void main(String[] args) {
        
        ApplicationContext context =
                new ClassPathXmlApplicationContext("beans.xml");//读取beans.xml 文件来创建一个应用程序上下文对象
         
        HelloWorldService service =
             (HelloWorldService) context.getBean("helloWorldService");
          
        HelloWorld hw= service.getHelloWorld();
         
        hw.sayHello();
    }
}

运行HelloProgram.java

修改beans.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd">
  
    <bean id="springHelloWorld"
        class="com.spring.test.helloWorld.impl.SpringHelloWorld"></bean>
    <bean id="strutsHelloWorld"
        class="com.spring.test.helloWorld.impl.StrutsHelloWorld"></bean>
  
    <bean id="helloWorldService"
        class="com.spring.test.helloWorld.HelloWorldService">
        <property name="helloWorld" ref="strutsHelloWorld"/><!-- IoC容器创建strutsHelloWorld对象并通过setter方法注入依赖 -->
    </bean>
  
</beans>

运行HelloProgram.java:

 

-----------------------------------------------------------------------------
 AaaServiceImpl.java继承 AbstractxxxService.java
public class AaaServiceImpl extends AbstractxxxService {
        
}
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:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"

    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 
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd 
        http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
    http://www.springframework.org/schema/task
    http://www.springframework.org/schema/task/spring-task.xsd"
    default-lazy-init="true">
    <!-- 任务定时器 -->
    <task:scheduler id="threadPoolTaskScheduler" pool-size="10" />
    <!--queue-capacity:队列容量;rejection-policy指定执行器队列满时的执行策略 1)ABORT(默认):直接抛出; 
        2)CALLER_RUNS:不会将任务交给执行器线程,而是让调用者线程来执行该任务; 3)DISCARD_OLDEST:丢弃老的政策; 4)DISCARD:丢弃政策 -->
    <task:executor id="threadPoolTaskExecutor" pool-size="10"
        queue-capacity="10" />

    <task:scheduled-tasks scheduler="threadPoolTaskScheduler">
        <task:scheduled ref="aaaService"
            method="run" cron="0/1 * * * * ?" />
    </task:scheduled-tasks>

    <!-- 父类 -->
    <bean id="autoCoreService" class="com.dscomm.remark.core.task.AbstractxxxService">
        <property name="xxxOperateService" ref="xxxOperateService" />
        <property name="singleObjectOperateFacade" ref="singleObjectOperateFacade" />
    </bean>
    
    <!-- 子类 -->
      <bean id="aaaService"
        class="com.dscomm.remark.regular.coc.execute.AaaServiceImpl">
        <property name="singleObjectOperateFacade" ref="singleObjectOperateFacade" />
      </bean>
</beans>

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:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"

    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 
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd 
        http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
    http://www.springframework.org/schema/task
    http://www.springframework.org/schema/task/spring-task.xsd"
    default-lazy-init="true">
    <!-- 任务定时器 -->
    <task:scheduler id="threadPoolTaskScheduler" pool-size="10" />
    <!--queue-capacity:队列容量;rejection-policy指定执行器队列满时的执行策略 1)ABORT(默认):直接抛出; 
        2)CALLER_RUNS:不会将任务交给执行器线程,而是让调用者线程来执行该任务; 3)DISCARD_OLDEST:丢弃老的政策; 4)DISCARD:丢弃政策 -->
    <task:executor id="threadPoolTaskExecutor" pool-size="10"
        queue-capacity="10" />

    <task:scheduled-tasks scheduler="threadPoolTaskScheduler">
        <task:scheduled ref="aaaService"
            method="run" cron="0/1 * * * * ?" />
    </task:scheduled-tasks>

    <!-- 父类 -->
    <bean id="autoCoreService" class="com.dscomm.remark.core.task.AbstractxxxService" abstract="true">
        <property name="xxxOperateService" ref="xxxOperateService" />
        <property name="singleObjectOperateFacade" ref="singleObjectOperateFacade" />
    </bean>

    <!-- 子类 -->
      <bean id="aaaService"
        class="com.dscomm.remark.regular.coc.execute.AaaServiceImpl"  parent="autoCoreService">
      </bean>
</beans>

子类只需要配置 parent="父类的bean ID"  ,这样,父类注入的属性,子类就不用再注入了,就可以直接父类的属性了。

-----------------------------------------------------------------------------
spring AOP
-----------------------------------------------------------------------------

配置参考:

<?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" xmlns:tx="http://www.springframework.org/schema/tx"
    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
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="find*" read-only="true" />
            <tx:method name="query*" read-only="true" />
            <tx:method name="get*" read-only="true" />
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut expression="execution(* org.mx..dao.I*Dao.*(..))"
            id="daoMethods" />
        <aop:pointcut expression="execution(* org.mx..task.I*Task.*(..))"
            id="taskMethods" />
        <aop:pointcut expression="execution(* com.business..I*Business.*(..))"
            id="businessMethods" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="daoMethods" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="taskMethods" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="businessMethods" />
        <aop:aspect id="LogAspect" ref="LogAspectBean">
            <aop:pointcut expression="execution(* org.mx..task.I*Task.*(..))"
                id="logsPointCut" />
            <aop:pointcut expression="execution(* com.business.I*Business.*(..))"
                id="logsPointCutBusiness" />
            <aop:around pointcut-ref="logsPointCut" method="businessLogAround" />
            <aop:around pointcut-ref="logsPointCutBusiness" method="businessLogAround" />
        </aop:aspect>
    </aop:config>
</beans>

 Spring

 

什么是spring AOP

答:

1.切面(Aspect):就是完成额外任务的类

2.连接点(Joinpoint):就是调用的目标方法

3.通知(Advice):切面中的方法

4.切入点(Pointcut):匹配连接点的断言。(执行通知的 if,就是一个匹配规则)

AOP的实现原理
答:

当获取对象时,首先将对象与切入点表达式进行匹配。如果匹配成功,
则会创建代理对象。然后代理对象执行方法时就会执行通知。

Spring bean的生命周期

 

 

1.首先容器启动后,会对scope为singleton且非懒加载的bean进行实例化,
2.按照Bean定义信息配置信息,注入所有的属性,
3.如果Bean实现了BeanNameAware接口,会回调该接口的setBeanName()方法,传入该Bean的id,此时该Bean就获得了自己在配置文件中的id,
4.如果Bean实现了BeanFactoryAware接口,会回调该接口的setBeanFactory()方法,传入该Bean的BeanFactory,这样该Bean就获得了自己所在的BeanFactory,
5.如果Bean实现了ApplicationContextAware接口,会回调该接口的setApplicationContext()方法,传入该Bean的ApplicationContext,这样该Bean就获得了自己所在的ApplicationContext,
6.如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessBeforeInitialzation()方法,
7.如果Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()方法,
8.如果Bean配置了init-method方法,则会执行init-method配置的方法,
9.如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization()方法,
10.经过流程9之后,就可以正式使用该Bean了,对于scope为singleton的Bean,Spring的ioc容器中会缓存一份该bean的实例,而对于scope为prototype的Bean,每次被调用都会new一个新的对象,期生命周期就交给调用方管理了,不再是Spring容器进行管理了
11.容器关闭后,如果Bean实现了DisposableBean接口,则会回调该接口的destroy()方法,
12.如果Bean配置了destroy-method方法,则会执行destroy-method配置的方法,至此,整个Bean的生命周期结束

 

 

 

以上是关于Spring-IOC的主要内容,如果未能解决你的问题,请参考以下文章

Spring-IOC学习笔记-01初识

Spring-IOC

spring-IOC

spring-ioc

Spring-IOC注入

二:Spring-IOC源码