Spring框架就是个大杂烩(使用它后其他好多框架的配置文件都会被统一管理),它集成了好多技术,它的核心就是IOC控制反转(以前我们创建对象时,控制权都在自己手中,因为需要自己去new对象,而用了spring后,它的ioc容器也就是spring的核心内裤会给我们自动创建对象并且可以注入属性,控制权就不在我们手上,即控制权反转了)Spring的ioc是用DI即依赖注入实现的,Spring里面包含的内容那是相当庞大的,但我感觉用的最普遍的就是它的IOC和AOP
1、
(1)spring.jar这是核心包,还有就是再加上两个关于日志的包log4j-1.2.14.jar和commons-logging.jar就行了,由于我们要 用spring的AOP,所以在加个aspectj下的两个jar包。
(2)接下来可以在spring提供的例子中拷贝applicationContext.xml和log4j.properties,我建的是Java项目
就直接考到src下(记得自己的项目尽量别放在有中文的目录,这样很可能会出问题)。
好了,基本工作就已经OK了
2、Spring 注入对象时可以用构造函数和set方法,但一般用set方法比较多。
3、当你给UserAction中注入了UserDAO,那么当你创建UserAction时就不能new了,必须从spring容器中获得,否则UserDAO无法
注入进来。
4、Spring 中可以有多个配置文件,但<bean id="">这个id不能重复,虽然我们表面上看有好多个配置文件,但我们一起加载时, 实质内部也是放在一块解析的。
5、org.springframework.beans.factory.config.CustomEditorConfigurer这是Spring提供的属性类型转换器。
6、在spring容器中如果有许多重复的属性要配置,那么为了减少配置量可以配置公共的属性,后面加上abstract="true",在需要 加入这些公共属性的bean后加上parent="公共bean的id"
7、Spring 默认注入返回的实例都是单实例,即你第二次调用getBean方法返回同一个类实例,不会再次创建,但可以在容器中配 置它为多实例。
8、Spring 中还提供了自动装配功能比如:根据名称装配(即在注入时不用配置类所依赖的属性,只要类中属性名跟配置文件的id 名称相等就行)、根据类型装配,这些都必须加额外的配置,spring默认是不支持的。
优点:可以减少依赖配置。缺点:看不出类对象的依赖关系。(不建议使用)
9、AOP面向切面编程,这个切面可以理解成我们的关注点也就是要操作或者代理的方法或类,Spring的AOP只针对方法。
10、JDK提供的动态代理要实现这个接口java.lang.reflect.InvocationHandler,JDK的动态代理实现条件就是目标类必须实现一 个接口。
11、spring的AOP默认用JDK的动态代理实现,还可以有其他方式,比如:cglib,只要引入cglib的jar包再到ioc配置中设置一下 就可以了,如果目标对象没有实现接口就要用cglib实现动态代理,cglib实现代理是创建目标对象的子类,因此目标对象不能 是final类型的。(我们在aop中也可以不用配置cglib的启动,如果我们的目标对象实现了接口则spring默认会采用jdk的动态 代理,如果某些类没有实现接口,则spring会自动切换到cglib,前提是加入了cglib的jar包)
12、spring的AOP实现方式:
(1)注解Annotation的方式——要加入两个aop实现包(lib/aspectj/中的两个jar包),spring对它做了集成(默认内部就是用JDK动态代理实现的)。
(2)采用配置方试——跟上面需要的包一样,然后去ioc容器中配置。
一下列出spring的简单配置:
1、先看下常用注入方式
<!-- 这里id就是ioc容器将要给你创建的对象的一个表示id,这个不能有重复,因为要在后台加载对象时用,class属性就
是ioc容器要装载类的全名 -->
<bean id="userDao" class="com.mwt.daoImlements.UserDAO"/>
<bean id="departDao" class="com.mwt.daoImlements.DepartDAO"/>
<!-- 先采用构造器注入 -->
<bean id="userService" class="com.mwt.service.UserService">
<!-- 这里的ref就是引用上面已经配置好的类(也就是要注入的类) -->
<constructor-arg ref="userDao"/>
</bean>
<!-- 下面采用set方式注入 -->
<bean id="departService" class="com.mwt.service.DepartService">
<!-- 这里的property就指的是类中的域,name就是域的名字,ref跟上面的ref一样即所引用要注入的类 -->
<property name="departDao" ref="departDao"/>
</bean>
2、普通属性注入
<bean id="user" class="com.mwt.bean.User">
<property name="name" value="马文涛"/>
<!-- 换种方式注入值 -->
<property name="age">
<value>728</value>
</property>
<property name="list">
<list>
<value>list1</value>
<value>list2</value>
</list>
</property>
<property name="set">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
<property name="map">
<map>
<entry key="k1" value="v1"/>
<entry key="k2" value="v2"/>
</map>
</property>
<!-- 数组也用list去注入 -->
<property name="c">
<list>
<value>a</value>
<value>b</value>
</list>
</property>
<!-- 注入Date类型属性 -->
<property name="date" value="2010-04-16"/>
</bean>
3、注解AOP配置:
/**
* 切面类,此类定义完后要在ioc容器中配置此类和目标类
* @author mawentao
* 类前面这个注解就声明了我们这是切面
*/
@Aspect
public class Annotation {
/*
* 此方法没实际意义,不会被调用,只是用它的方法名做个标示
* 此方法是公共的、没返回值、没参数
* 用注解声明切点的描述,第一个*代表返回值可以是任何东西,save*代表方法名以save开头的(spring的aop只是针对于方法),最后的(..)
* 标示可以带任何参数
*/
@Pointcut("execution(* save*(..))")
public void markMethod(){}
/**
* 在切点前要加的检查方法
* 用注解声明在哪个切入点包括何时织入此方法
*/
@Before("markMethod()")
public void checkMethod(){
System.out.println("spring注解aop实现方法检查");
}
}
配置文件如下:
<!-- 启用spring的注解aop实现 -->
<aop:aspectj-autoproxy/>
<!-- 由于上面开启了aop的注解实现,则当我们在后台通过ioc获得此dao时spring会给我们返回一个实现了和userDao相同接口的代理 -->
<bean id="userDao" class="com.mwt.daoImlements.UserDAO"/>
<!-- 下面这个切面类的注入id随便起名字,因为id用不到,但这个类还必须注入,ioc会自动实例化这个对象 -->
<bean id="annotation" class="aop.annotation.Annotation"/>
4、采用纯配置文件配置AOP实现:
package aop.config;
import org.aspectj.lang.JoinPoint;
/**
* 切面类,此类直接在ioc容器中配置
* @author mawentao
*/
public class AopConfig {
/**
* 要给切点织入的方法,在检查方法中也可以获得目标方法的名字和参数,它们都封装在JoinPoint这个对象中。
*
*/
public void checkMethod(JoinPoint joinPoint){
Object[] obj = joinPoint.getArgs();//获得参数列表
for(Object o:obj){
System.out.println(o);
}
System.out.println("方法名:"+joinPoint.getSignature().getName());
System.out.println("spring配置aop实现方法检查");
}
}
下面是配置:
<bean id="userDao" class="com.mwt.daoImlements.UserDAO"/>
<!-- 下面这个是切面类 -->
<bean id="aopConfig" class="aop.config.AopConfig"/>
<aop:config>
<aop:aspect id="myAspect" ref="aopConfig">
<!-- 给切点加个标示即id,expression就是要匹配的表达式(第一个*是返回值,然后再跟上包名,也可以不跟包,紧接着..*代表当前包和子包,然后再.save*(..)代表所有save开头,任何参数的方法) -->
<aop:pointcut id="markMethod" expression="execution(* com.mwt.daoImlements..*.save*(..))"/>
<!-- 切点应用的时刻和要织入的方法,再还要引用切点 -->
<aop:before method="checkMethod" pointcut-ref="markMethod"/>
</aop:aspect>
</aop:config>
|