Spring 核心IOC, AOP简介

1、IOC 控制反转

       IoC叫控制反转,是Inversion of Control的缩写,控制反转是把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的"控制反转"就是对组件对象控制权的转移,从程序代码本身转移到了外部容器,由容器来创建对象并管理对象之间的依赖关系。

    控制反转——Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象,是容器在对象初始化时不等对象请求就主动将依赖传递给它。通过IOC反转控制DI依赖注入完成各个层之间的注入,使得层与层之间实现完全脱耦,增加运行效率利于维护。

    就是把控制权反转。一般程序都是我们主动new 对象实例,我们拥有控制权。但是通过spring配置,可以使用spring容器帮我们实例化对象,并且也可以注入参数。这里相当于我们吧我们的控制权交给了spring容器,实现了控制的反转。

例如:(setter注入)

public class Person{
	private String name;
		
	public void setName(String name){
		this.name = name;
	}
		
	public void info(){
		System.out.println("名字是: " + name);
	}
}

         Spring吧该类部署到Spring容器文件中,在Spring配置文件中增加如下片段(默认spring bean是单例模式)

<bean id = "person" class="con.zds.Person">
	<porperty name="name" value="tom">
</bean>

          在主程序中调用该类就变成了这样:

Person p = ctx.getBean("person", Person.class);
p.info();

        上面两行代码不是直接创建Person实例,而是通过Spring容器获取Person实例,这正是Spring容器的作用。Spring不仅可以实例化对象,还可以为对象中的属性赋值。---这种由Spring容器为对象设置属性的方式被称为控制反转IOC

2、DI 依赖注入

   作用:使代码变得更简洁、耦合性更小。   

   什么叫依赖: 所有java应用,他们都是一种典型的依赖型应用。也就是由一些相互协作的对象构成的。Spring把这种互相协作的关系成为依赖关系。假如A组件调用了B组件的方法,我们可以称A组件依赖于B组件

   实例:任何一个有实际意义的应用都是有两个或者更多的类组成,这些类相互协作来完成特定的业务逻辑,通常,每个对象负责管理与自己相互协作的对象的引用,这将会导致高度耦合和难以测试的代码。如下:

public class Person {    
    private User user;        
    public Person(){        
        user = new User();    
    }       
}

    如上代码,在构造器中new了一个对象的实例,这使得User和Person紧密耦合在一起,User完全侵入了Person类中。如果在别处也要使用User对象,也会在需要的地方new出来。假如User类有所改变,会导致只要用到User实例的地方都需要更改。

   上面的代码紧耦合,紧耦合的代码难以复用,难以理解。 但是一定的耦合也是必须的,完全没有耦合的代码什么也做不了。使用依赖注入DI能很好解决这个问题。

public class Person{
	private User user;
	public Person(User user){
		this.user = user;
	}
}

上面就是依赖注入的方式之一(配置文件是下面的代码):构造器注入

依赖注入优点:松耦合

  要完成上面的注入必须要通过XML配置bean, 创建应用组件之间的协作的行为通常称为:装配。Spring有多种装配Bean的方式,采用XML配置是最常用的方式。下面创建一个applicationContext.xml文件。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.ws.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<bean id="person" class="com.zds.Person">
		<constructor-arg ref="user" />
	</bean>
	<bean id="user" class="com.zds.User" />
</beans>

    工作原理:Spring通过上下文(Application Context)装在Bean的定义并把他们组装起来。Spring应用上下文全权负责对象的创建和组装。Spring自带了几种应用上下文的实现,他们之间主要的区别仅仅是如何加载它们的配置。因为applicationContext.xml中的Bean是在XML中声明的,所以选择ClassPathXmlApplicationContext作为拥有上下文是比较合适的。该类加载位于应用系统classpath下的一个或者多个xml文件,ClassPathXmlApplicationContext加载applicationContext.xml,并获得Knight对象的引用。

装载Bean,并且注入到业务类中,进行测试,如下:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class KnightMain {
	public static void main(String[] args){
		AppcationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person= (Person)context.getBean("person");
		person.toString();  //用来验证是否注入,如果没有会报空指针异常
	}
}

3、AOP 应用切面

  依赖注入让互相协作的软件组件保持松散耦合,而AOP编程允许你吧遍布应用各处的功能分离出来形成可重用的组件。比如日志、事务管理、安全此类的系统服务经常融入到有自身核心业务的组件中去,这些系统服务通常被称为横切关注点,他们总是跨越系统的多个组件。

如下图:

                                                        

  AOP可以使这些服务模块化,并以声明的方式将他们应用到他们需要影响的组件中去。结果是这些组件具有高内聚性以及更加关注自身业务,完全不需要了解可能设计的系统服务的复杂性,总之,AOP确保POJO保持简单。如下:

         

  我们可以把切面想象为覆盖在很多组件之上的一个外壳,应用是由哪些实现各自业务功能的模块组成。利用AOP,你可以使用各种功能层去包裹核心业务层,这些层以声明的方式灵活应用到你的系统中,甚至你的核心应用根本不知道他们的存在。这可以将事务和日志关注点与你的核心业务逻辑分离。

简单的实例:

public class People {
	public void eatBeforeWan(){
		System.out.println("玩之前,要先吃饭··");
	}
	
	public void watherAfterWan(){
		System.out.println("完之后,要喝水···");
	}
}

上面People这个类有两个方法,在玩之前之后会分别调用这两个方法。吧这两个方法加入你的业务中,如下:

public void happy(){
	knight.eatBeforeWan();
	knight.wan();  //核心业务类
	knight.watherAfterWan();
}

  虽然上面的代码不太繁琐,但是可以看出,我不关心玩之前之后干什么,我只要业务是“玩”,在我做正事的时候,让我做一些其他无关的事情,这个总感觉不太好。这里通过使用AOP,就可以解决这些繁琐无用的代码,让我们只关注核心业务就可以了。

配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.ws.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	<!-- DI 依赖注入配置 -->
	<bean id="person" class="com.zds.Person">
		<constructor-arg ref="user" />
	</bean>
	<bean id="user" class="com.zds.User" />
	
	<!-- AOP 有关配置 -->
	<bean id="minstrel" class="com.springinaction.knights.Minstrel" />
	<aop:config>
		<aop:aspect ref="minstrel"><!-- 定义切面 -->
			<aop:pointcut id="embark" expression="execution(* *.embarkOnuest(..))" /><!-- 
				前置通知 -->
			<aop:before pointcut-ref="embark" method="eatBeforeWan" /><!-- 
				后置通知 -->
			<aop:after pointcut-ref="embark" method="watherAfterWan" />
		</aop:aspect>
	</aop:config>
</beans>















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值