Spring IOC容器

spring IOC 容器有两种,分别是 BeanFactory 容器和 ApplicationContext 容器。

BeanFactory如下:

/*第一步,利用ClassPathResource()API加载路径CLASSPATH下的可用的Bean的xml配置文件
然后利用框架提供的 XmlBeanFactory() API生成工厂Bean,XmlBeanFactory()负责创建和初始化所有对象
然后用getBean方法得到所需要Bean并转化类型为真正的对象
*/
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("Beans.xml"));
HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");
obj.getMessage();
<?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-3.0.xsd"> <bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
<property name="message" value="Hello World!"/>
</bean> </beans>

ApplicationContext接口的实现:

FileSystemXmlApplicationContext:从xml文件中加载已经被定义的bean,需要提供的参数为完整的XML文件路径

ClassPathXmlApplicationCOntext:从xml文件中加载已经被定义的bean,但从CLASSPATH加载xml文件

package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
//第一步
ApplicationContext context = new FileSystemXmlApplicationContext("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml");
//第二步
    HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
}
}

Spring Bean 的作用域

singleton:是bean的默认作用域;当作用域为singleton时,IOC容器只会存在一个共享的bean实例,多次getBean时,返回的都是同一个Bean

<bean id="..." class="..." scope="singleton">
<!-- collaborators and configuration for this bean go here -->
</bean>

prototype:表示一个bean的定义对应多个对象实例,每次getbean时都会返回一个新的bean实例;

spring的依赖注入

基于构造函数的注入

<!-- id是bean的id,用于识别bean; class是bean所对应的类-->
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
<!--constructor-arg表示基于构造函数注入 ,ref表示注入的值是引用而非一般的数值-->
<constructor-arg ref="spellChecker"/>
</bean>
   <bean id="foo" class="x.y.Foo">
<!-- 当构造函数存在多个参数时,按顺序定义即可按顺序传参-->
<constructor-arg ref="bar"/>
<constructor-arg ref="baz"/>
</bean>

基于设值函数的依赖注入

   <bean id="textEditor" class="com.tutorialspoint.TextEditor">
<property name="spellChecker" ref="spellChecker"/> <!-- property表示基于设值函数注入,设值函数的名字一定要是 setSpellChecker()-->
<property name="name" value="John Doe"/> <!-- name是属性的名字,value是属性的值-->
</bean>

基于注解的配置

注解

@required:用在set方法上,一旦用了这个注解,bean在初始化时就必须对这个值进行依赖注入;否则报错

public class Zoo {
private Dog dog ;
public Dog getDog() {
return dog;
}
@required //如果xml文件中没有对Dog属性进行注入,则会报错
public void setDog(Dog dog) {
this.dog = dog;
}
}

@Autowired:可以不写依赖注入的配置,让容器自己寻找依赖并注入

public class Zoo {
@Autowired private Dog dog ;
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}

基于注解的注入

在xml配置中添加下列语句,告诉spring要用注解的方式进行配置

<context:annotation-config/>
import org.springframework.beans.factory.annotation.Autowired;

public class Product {     
private int id;
//在属性前加上Autowired注解,实现注入;
//这时Category属性就可以不要set函数了,在xml中的Product的bean也不能再配置Category属性了;但product的bean还是需要的;
//如果在xml中的product的bean中也配置了Category属性,则会按照xml优先的原则寻找属性对应的set函数或者构造函数,如果找不到则报错
@Autowired
private Category category; public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
//也可以在设值函数前加上Autowired注解,实现注入;
//这种情况下同上,可以不用在xml文件中配置category属性,但product的bean还是需要声明的
@Autowired
  public void setCategory(Category category) {
    this.category = category;
  }
}

此时的xml:仅仅去掉了对属性是引用的Category属性的配置,其它的并没有省略;(省略的是下方注释的那一行)

<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/>
<bean name="c" class="com.how2java.pojo.Category">
<property name="name" value="category 1" />
</bean>
<bean name="p" class="com.how2java.pojo.Product">
<property name="name" value="product1" />
<!-- <property name="category" ref="c" /> -->
</bean> </beans>

进一步省略基于注解的注入

先将xml中的什么都去掉,只新增一行<context:component-scan base-package="com.how2java.pojo"/>,这时告诉spring,bean在哪个java包下

<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.how2java.pojo"/> </beans>

然后在java文件中做如下改动

package com.how2java.pojo;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; //@component表明Product类是bean,这相当于在xml中声明一个bean
@Component("p")
public class Product {
//属性的初始化现在放在属性声明中进行
private int id = 10;
private String name="product 1";
//同上,对Category属性进行自动注入
@Autowired
private Category category; }

Spring AOP

aop概念

连接点(joinpoint):一个类或者一段程序拥有的具有边界性质的特定点,叫做连接点。

切点(pointcut):是某些特定的连接点;如果用数据库的概念来比喻连接点和切点的关系,连接点相当于客观存在的记录数据,而切点相当于查询条件;

增强(advice):增强是织入到连接点上的一段程序代码(就是一个方法);

目标对象:要被织入代码的类

切面:切面 = 增强 + 切点

基于xml的aop

服务类:

import org.aspectj.lang.ProceedingJoinPoint;
//增强所在的类
public class LoggerAspect {
//增强,即要织入的方法
public void log(JoinPoint joinPoint) throws Throwable {
System.out.println("start log");
return object;
}
}  

xml配置:

<!-- 声明业务类对象-->
<bean name="s" class="com.how2java.service.ProductService">
</bean>
<!-- 声明服务类对象-->
<bean id="loggerAspect" class="com.how2java.aspect.LoggerAspect"/> <aop:config>
<!-- id是切入点的名字,定义了一个切点 -->
<!-- expression 表示满足这个expression 的方法在被调用之后,就会执行切面操作,相当于触发了切面;-->
<!--第一个*表示返回值返回任意类型,第二个*表示任意方法,(..)表示方法的参数是任意数量和类型 -->
<aop:pointcut id="loggerCutpoint" expression="execution(* com.how2java.service.ProductService.*(..)) "/>
<!-- 定义了一个切面,切面 = 增强 + 切点-->
<!-- id是切面的名字, ref是增强所在的类-->
<aop:aspect id="logAspect" ref="loggerAspect">
<!-- pointcut-ref 表示本切面和哪个切点相关联; method代表增强-->
<!-- aop:after 表示要在何时调用增强;before在方法调用前,after在方法调用后,after-returning在方法执行成功后-->
<!-- after-throwing在方法抛出异常后调用;around在方法调用前和调用后执行-->
<aop:after pointcut-ref="loggerCutpoint" method="log"/>
</aop:aspect>
</aop:config>

基于注解方式的aop

业务类如下:

package com.how2java.service;
import org.springframework.stereotype.Component;
//用component来声明这是一个bean
@Component("s")
public class ProductService {
public void doSomeService(){
System.out.println("doSomeService");
}
}

服务类如下:

package com.how2java.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
//Aspect注解表示这是一个切面,component注解声明了一个bean
@Aspect
@Component
public class LoggerAspect {
//around注解表示对目标类中的某些方法进行切面操作
@Around(value="execution(*com.how2java.service.ProductService.*(..))")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("start log:" + joinPoint.getSignature().getName());
Object object = joinPoint.proceed();
System.out.println("end log:" + joinPoint.getSignature().getName());
return object;
}
}

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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 下面两行是告诉spring应该扫描哪些包-->
<context:component-scan base-package="com.how2java.aspect"/>
<context:component-scan base-package="com.how2java.service"/> <aop:aspectj-autoproxy/> </beans>

spring IOC与AOP的更多相关文章

  1. 【转】spring - ioc和aop

    [转]spring - ioc和aop 1.程序中为什么会用到spring的ioc和aop 2.什么是IOC,AOP,以及使用它们的好处,即详细回答了第一个问题 3.原理 关于1: a:我们平常使用对 ...

  2. J2EE进阶(十四)超详细的Java后台开发面试题之Spring IOC与AOP

    J2EE进阶(十四)超详细的Java后台开发面试题之Spring IOC与AOP 前言   搜狐畅游笔试题中有一道问答题涉及到回答谈谈对Spring IOC与AOP的理解.特将相关内容进行整理.    ...

  3. spring - ioc和aop

    1.程序中为什么会用到spring的ioc和aop 2.什么是IOC,AOP,以及使用它们的好处,即详细回答了第一个问题 3.原理 关于1: a:我们平常使用对象的时候,一般都是直接使用关键字类new ...

  4. Spring IOC及AOP学习总结

    一.Spring IOC体系学习总结: Spring中有两个容器体系,一类是BeanFactory.还有一类是ApplicationContext.BeanFactory提供了基础的容器功能.Appl ...

  5. Spring ioc与aop的理解

    一 spring的特点 1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它很容易 ...

  6. Spring IOC、AOP、Transaction、MVC小结

    1.IOC.AOP:把对象交给Spring进行管理,通过面向切面编程来实现一些“模板式”的操作,使得程序员解放出来,可以更多的关注业务实现.                             - ...

  7. BeanPostProcessor —— 连接Spring IOC和AOP的桥梁

    之前都是从大Boss的视角,来介绍Spring,比如IOC.AOP. 今天换个视角,从一个小喽啰出发,来加深对Spring的理解. 这个小喽啰就是, BeanPostProcessor (下面简称 B ...

  8. spring IOC 和AOP 方面

    spring 的2大核心 是Ioc 和 aop  spring的依赖注入:在程序运行期间,由外部容器动态的将依赖对象注入到组件中  IOC: 实例化spring容器的二种方法 第一种:在类路径下寻找配 ...

  9. 黑马-Spring(IOC&DI) AOP

    IOC(控制翻转) 概念 把对象的创建.初始化.销毁等工作交给spring容器来做 案例 环境 步骤 1.  写一个HelloWorld类 2.  写一个配置文件   把hello类放到spring容 ...

随机推荐

  1. 编程心法 之什么是MVP What is MVP development?

    Minimal Value product(feather), 比如说,如果是一个新的Photoshop,那么增加图片亮度就是一个MVP. 想要看到更多玮哥的学习笔记.考试复习资料.面试准备资料?想要 ...

  2. 解决IE6-IE7下li上下间距变大问题

    在IE6/7下li会向下产生大约2px的外边距 解决方法:li{vertical-align:top;}或者       li{vertical-align:bottom;} 解决问题!

  3. phpStudy2018安装与配置步骤详解

    phpStudy 2018是一款非常强大的php环境调试工具,一次性安装,无须配置即可使用,是非常方便.好用的PHP调试环境.对学习PHP的新手来说,WINDOWS下环境配置是一件很困难的事:对老手来 ...

  4. DevExpress TreeList 禁止节点拖动到其他节点上

    背景 在做一个类似文件树的控件,支持节点从树上向其它的控件拖动程序,但是要保证树上的节点不能拖动上其他的节点上. 代码 /// <summary> /// 拖动节点完成 /// </ ...

  5. Django 列的自定义显示

    ModelAdmin 作用:对后台数据表的显示做自定义的设置(如果对django默认的显示模式感到满意则不需要定义modeladmin).我对默认的显示模式永远不满意! 定义modeladmin: f ...

  6. Centos6搭建vsftpd

    CentOS 6.5下安装Vsftp,虚拟用户一.安装:1.安装Vsftpd服务相关部件:[root@localhost ~]# yum install vsftpd*Loaded plugins: ...

  7. MongoDB自学(3)

    MongoDB关系:MongoDB的关系表示多个文档之间在逻辑上的相互联系.文档之间可以通过嵌入和引用来建立联系.关系:1:11:NM:1M:N 嵌入式:{ id:11;name:嘻嘻嘻;addres ...

  8. 简单的纯js三级联动

    参考这个  日尼禾尔  二级联动 写了三级联动 <!DOCTYPE html> <html> <head> <meta charset="UTF-8 ...

  9. 记录未预编译文件“*.aspx”,因此不能请求该文件的几种处理办法

    对应Framework版本重新注册 2.0:C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -i 4.0:C:\Wind ...

  10. #032 有空就看PTA

      我咋买书了? 上学期