-
基于泛型的自动装配(Spring4新增的内容,和SPI使用方式相似,只不过Spring提供了更简便的使用方式。API:应用编程接口。SPI:针对服务框架开发或者一些工具的基础使用的特殊类型接口。)
基于依赖对象泛型的自动装配案例
步骤1:
public class IntegerStore {
}
public class StringStore{
@Autowired
private IntegerStore s2;
public void print(){
System.out.println("s2: "+s2);
}
}
步骤2:
@Configuration
public class StoreConfig {
@Bean
public StringStore stringStore(){
return new StringStore();
}
@Bean
public IntegerStore integerStore(){
return new IntegerStore();
}
}
步骤4:测试
@Test
public void testStore(){
ApplicationContext ac=new AnnotationConfigApplicationContext(StoreConfig.class);
StringStore ss=ac.getBean("stringStore",StringStore.class);
ss.print();
}
结果:(如果不加@Autowired注解,s2:为空)
s2: IntegerStore@3323f4c5
基于集合泛型的自动装配(注意:不能使用@Autowired注解,要使用@Resource注解,并且使用@Resource(name="名字1"),去匹配@Bean(name="名字1")。
步骤1:
public class IntegerStore {
}
public class StringStore {
public StringStore() {
System.out.println("无参构造方法执行了");
}
private List<IntegerStore> list;
@Resource(name = "ll")
public void setList(List<IntegerStore> list) {
this.list = list;
}
public void print() {
for (IntegerStore store : list) {
System.out.println(store);
}
}
}
步骤2:
@Configuration
public class StoreConfig {
@Bean(name = "ll")
public List<IntegerStore> ll() {
List<IntegerStore> lis = new ArrayList<IntegerStore>();
lis.add(new IntegerStore());
lis.add(new IntegerStore());
lis.add(new IntegerStore());
return lis;
}
@Bean(name = "stringStore")
public StringStore stringStore() {
return new StringStore();
}
}
测试:
@Test
public void testStore() {
ApplicationContext ac = new AnnotationConfigApplicationContext(StoreConfig.class);
StringStore ss = ac.getBean("stringStore", StringStore.class);
ss.print();
}
}
结果:
无参构造方法执行了
IntegerStore@2b2c8b14
IntegerStore@795ee430
IntegerStore@44d74990
Autowired扩展——自定义qualifier注解(自定义自动化注入配置)
查看全部 -
Advisors
1、advisor就像一个小的自包含的方面,只有一个advice。
2、切面自身通过一个bean表示,并且必须实现某个advice接口,同时,advisor也可以很好的利用AspectJ的切入点表达式(后面介绍AspectJ实现AOP时会介绍到AspectJ的切入点表达式)。
3、Spring通过配置文件中<aop:advisor>元素支持advisor,实际使用中,大多数情况下它会和transactional advice(事物相关的advice)配合使用(也可以有其他使用方式,根据项目或者工程的实际情况来决定)。
4、为了定义一个advisor的优先级以便让advice可以有序,可以使用order属性来定义advisor的顺序。
advisor的配置(<tx:advice>是对于事物的相关声明,通过这种方式使用advisor,这种方式是在使用Spring事物的控制时,经常使用的方式)
案例:(没有讲解advisor的案例,讲解了环绕通知的一个案例,适用场景:统计逻辑功能方法的调用次数,例如统计某方法调用3次,就不让调用了)
步骤1:
public class ServiceFunction {
public void print1(){
System.out.println("逻辑功能方法1执行了");
}
public void print2(){
System.out.println("逻辑功能方法2执行了");
throw new RuntimeException();
}
}
步骤2:
public class AspectFunction {
private int max_times;
public int getMax_times() {
return max_times;
}
public void setMax_times(int max_times) {
this.max_times = max_times;
}
public Object aspectFunction(ProceedingJoinPoint pjp) throws Throwable{
int num_times=0;
do{
num_times++;
try{
System.out.println(num_times+"次");
return pjp.proceed();
}catch(RuntimeException e){
}
}while(num_times<=max_times);
System.out.println("方法总共执行了"+num_times+"次");
return null;
}
}
步骤3:
查看全部 -
什么是spring
查看全部 -
Introductions应用(简介的advice,作用:在不改变对象和类的代码的前提下,为对象和类添加新的方法。)
Introduction定义:简介允许一个切面声明一个实现指定接口的通知对象,并且提供一个接口实现类(接口的实现类,来代表实例化好的Bean)来代表这些对象。
Introductions的实现:由<aop:aspect>中的<aop:declare-parents>元素声明,该元素用于声明所有匹配的类型,拥有一个新的parent(接口声明的对象可以指向getBean获得的对象)。
<aop:declare-parents>属性
type-matching="expression表达式(表示匹配什么样的类型)。
implement-interface="接口的路径"(切面类的接口)。
default-impl=“切面类的路径”。
案例:
步骤1:编写逻辑功能接口(限制逻辑功能),并提供它的实现类。
public interface ServiceInterfaceFunction {
public void print();
}
public class ServiceFunction implements ServiceInterfaceFunction {
@Override
public void print() {
System.out.println("逻辑功能接口实现类的方法执行了");
}
}
public class ServiceGongNeng {
}
步骤2:配置<aspect:config>(有接口的SpringAOP实现,使用JavaSE动态代理,也就是JDK代理,JDK动态代理只能对实现了接口的类生成代理,而不能针对类,所以要配置<aop:declare-parents>)。
步骤3:测试
@Test
public void testaop(){
ApplicationContext ac=new ClassPathXmlApplicationContext("spring-aop-schema-advice.xml");
ServiceInterfaceFunction sif=(ServiceInterfaceFunction)ac.getBean("serviceGongNeng",ServiceGongNeng.class);
sif.print();
}
结果:正常可以执行接口实现类里的方法。(注意:types-matching="springAOP.ServiceGongNeng"没有execution)
重点扩展:所有基于配置文件的aspects,只支持单例模式(Single Model)。
查看全部 -
Advice应用下
Around advice(环绕通知):切面方法的第一个参数必须是ProceedingJoinPoint类型。(并且在这个切面方法里,有一个proceed()方法:当前业务方法的返回值,无论是void类型还是其他类型返回值,都使用Object retVal=pjp.proceed()这种方式,业务方法执行前(这行代码前)业务方法执行后(这行代码后),都可以做我们的切面功能,最后返回retVal对象。)
Around advice案例(配置了环绕通知,抛出异常通知就无效了,因为环绕通知的方法始终有返回值,pjp.proceed()表示逻辑方法的执行,如果逻辑方法抛出异常,根据是否要进行处理在环绕通知的方法里进行捕获或者往外抛出)
步骤1:spring配置
步骤2:切面的环绕通知方法。
public Object aroundAspect(ProceedingJoinPoint pjp){
Object obj=null;
try {
System.out.println("切面的前环绕通知功能实现了");
obj = pjp.proceed();
System.out.println("切面的后环绕通知功能实现了");
} catch (Throwable e) {
e.printStackTrace();
}
return obj;
}
Advice parameters(通知方法里的参数):逻辑功能方法的参数,通过配置,可以传入到切面的通知方法里。
案例(环绕通知参数)
步骤1:编写逻辑功能的方法,并有两个参数。
步骤2:编写配置文件,切面、环绕通知等(注意:配置方法里的参数名要和逻辑方法参数名相同,并且环绕通知方法名和参数名相同)。
测试:
@Test
public void test(){
ApplicationContext ac=new ClassPathXmlApplicationContext("spring-aop-schema-advice.xml");
ServiceFunction sf=ac.getBean("serviceFunction",ServiceFunction.class);
sf.serviceFunction("小明",5);
}
结果:
切面前置通知功能实现了
名字为小明
5次
切面的前环绕通知功能实现了
逻辑功能实现了
切面的后环绕通知功能实现了
切面后置通知功能实现了
切面返回后通知功能实现了
查看全部 -
Advice应用(advice的配置)
Before advice的两种配置方式
<aop:before pointcut-ref="切入点的Id" method="切面的方法"/>。直接设置切入点(就不用单独设置<aop:point-cut/>标签了)
<aop:before pointcut="execution(* com.xyz.myapp.dao..(..))" method="doAccessCheck"/>
案例:(前置)
步骤1:编写逻辑功能类、切面功能类、并编写各自的方法。
代码:
步骤2:编写XML配置,实例化逻辑功能类的Bean和切面功能类的Bean,配置切面、切入点、通知。
案例:(After return advice返回后通知)
<aop:after-returning>returning属性,限制方法的返回值,例如retVal。(arg-names为参数名称,它是严格匹配的。)
步骤1:编写逻辑功能类、切面功能类、并编写各自的方法(和以上相似,只不过切面类多了一个方法)。
步骤2:编写XML配置,实例化逻辑功能类的Bean和切面功能类的Bean,配置切面、切入点、通知。
案例:(抛出异常后通知After throwing advice,<aop:after-throwing>标签多了一个throwing属性,它是限制可被传递的异常参数名称)
步骤1:编写逻辑功能类、切面功能类、并编写各自的方法(编写发生异常后切面要执行的方法)
步骤2:编写XML配置,实例化逻辑功能类的Bean和切面功能类的Bean,配置切面、切入点、抛出异常通知。
案例:(后置通知After (finally) advice)
步骤1:编写逻辑功能类、切面功能类、并编写各自的方法(编写逻辑方法执行后要执行的切面方法)
步骤2:编写XML配置,实例化逻辑功能类的Bean和切面功能类的Bean,配置切面、切入点、抛出异常通知。
案例:(环绕通知After (finally) advice)
步骤1:编写逻辑功能类、切面功能类、并编写各自的方法(编写逻辑方法执行后要执行的切面方法)
步骤2:编写XML配置,实例化逻辑功能类的Bean和切面功能类的Bean,配置切面、切入点、抛出异常通知。
查看全部 -
spring是一个轻量级的 控制反转(Ioc)和面向切面(AOP)的容器框架
IOC: 轻量级的控制反转,达到松耦合的目的
将控制权交出去,使用时得到对象
AOP:面向切面,允许通过分离应用的业务逻辑与系统级服务进行内聚性的开发----例如仓库管理的业务逻辑和日志记录的系统服务
事务管理,日志等
查看全部 -
spring 资源
查看全部 -
配置切入点Pointcut(找到某个功能模块的具体方法)
execution用于匹配某个功能模块的具体方法。
以下SpringAOP和Spring支持的AspectJ都支持。
图一的1:执行所有的public方法时,进行切入(执行相应切面的相应功能)。
图一的2:执行所有的set方法时,进行切入。
图一的3:执行com.xy.service.AccountService类下的所有方法时,进行切入。
图一的4:执行com.xyz.service包下的所有方法时,进行切入。
图一的5:执行com.xyz.service包下以及子包下的所有方法时,进行切入。
以下为SpringAOP自己支持的。
SpringAOP其他的匹配。
图一的1:匹配目标对象。
图一的2:匹配参数的。
图一的3:按注解匹配的。
图一的4:按注解匹配的。
图一的5:按注解匹配的。
图二的1:参数里采用了何种注解。
图二的2:采用了何种bean。
图二的3:bean是以何种形式进行结尾的。(这些可以去Spring官方文档和搜索引擎搜索,会有很全面的解释,这些切入点会有很多类型,在具体使用时,可以查找相应文档)
完整的AOP配置(根据不同业务需求,查找相关文档,进行不同的expression表达式配置)
案例1:表示执行service包下的所有类的任何类型的方法时,进行切入。
案例2:表示执行SystemArchitecture的businessService()方法时,才进行切入。
案例3:执行AspectBiz中的所有方法,都会进行切入。
配置以某个单词结尾的类:例如上面Aspect编写成*。
查看全部 -
基于Schema-based配置的AOP实现
Spring所有的切面和通知器都必须放在<aop:config>内(可以配置多个<aop:config>元素),每一个<aop:config>可以包含aspect,pointcout和advisor元素(它们必须按照这个顺序进行声明)。
<aop:config>的配置大量使用了Spring的自动代理机制。
该配置的含义:一个类作为切面来声明,切面Id是myAspect,也就是说程序执行某个功能模块时,通过pointcut和Joinpoint执行该切面的功能。
案例:两个类,一个类作为切面类,另一个作为业务类。(注意:<beans>中添加约束,xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
)
代码:
<?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"
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-4.0.xsd">
<bean id="aspectImooc" class="aspect.AspectImooc"></bean>
<bean id="ServiceImooc" class="aspect.ServiceImooc"></bean>
<aop:config>
<aop:aspect id="aspectImoocAop" ref="aspectImooc"></aop:aspect>
</aop:config>
查看全部 -
AOP基本概念及特点
一、什么是AOP及实现方式
AOP:Aspect Oriented Programming,面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
主要功能:日志记录,性能统计,安全控制,事物处理,异常处理等等。(事务处理:任何操作数据库的方法,尤其是增删改,需要事物的处理,使用AOP时,执行到某种类型的方法,或者某一层的类,自动开启事物和获取连接、提交事物、关闭事物的步骤,简化了操作)
AOP实现方式:1——预编译方式。(AspectJ)
2——运行期动态代理。(JDK动态代理、CGLib动态代理)
(SpringAOP、JbossAOP)
切面的理解:例如系统中有产品管理、订单管理、服务管理等等模块(子功能),任一模块(子功能),都需要记录它的日志,控制它的事物,以及做一些安全验证的功能。但是如果在每一个模块(子功能)中去设计日志、事物、安全验证,会带来大量工作量,尤其当项目达到一定规模时,比如修改日志记录的方式,那么则需要修改每一个模块的日志功能,通过切面方式对开发人员是不可见的,当执行任一模块时,通过预编译或者运行期动态代理方式,都会去记录它的日志,实现了一处写功能,处处可实现的方式,对于开发人员允许不知道有这样功能的存在,这样就简化了操作(修改日志、编写事物等),业务功能横向走,切面垂直业务功能。
二、AOP基本概念(切面—>织入—>目标对象—>切入点—>连接点—>通知—>引入—>AOP代理:“切面”要执行的动作,通过“织入”与所有功能模块进行联系,又通过“目标对象”找到具体功能模块,通过“切入点”将要查找某个功能的某个方法,通过“连接点”找到该功能的特定方法的开始,通过“通知”将要执行何种切面的动作,通过“引入”引入该动作用到的对象和方法,通过“AOP代理”实现该方法。)
AOP相关概念:
1、切面(Aspect):一个关注点(事物),这个关注点可能会横切多个对象(产品管理、订单管理)。
2、连接点(Joinpoint):程序执行过程中的某个特定的点。(一个类中执行的某个方法的开始)。
3、通知(Advice):在切面的某个特定的连接点上执行的动作(方法执行的时候,切面额外执行的动作,比如说方法执行时,开启事物提交功能)。
4、切入点(Pointcut):匹配连接点的断言,在AOP中通知和一个切入点表达式关联(在切面中匹配一个具体的连接点(某个功能的方法的开始))。
5、引入(Introduction):在不修改类代码的前提下,修改的是字节码文件,为类添加新的方法和属性。(类似于编译期动态的修改class文件去增加新的属性和方法,源代码中并没有这样的属性和方法),取决于使用AspectJ和SpringAOP的实现方式,使用方式不同,为类添加属性和方法的方式是有区别的。
6、目标对象(Target Object):被一个或者多个切面所通知的对象。(例如存在一个订单的service(对象)和一个商品的service(对象),执行该模块的功能时,切面会通知相对应的service,在执行数据库操作时,去加上事物的控制,这两个service就是目标对象)。
7、AOP代理(AOP Proxy):AOP框架创建的对象,用来实现切面契约(aspect contract),包括通知方法执行等功能(这里执行的方法指的是切面里的执行相应操作所用到的方法)开发时不知道这个对象存在的,也不清楚会创建成什么样子。
8、织入(Weaving):把切面连接到其他的应用程序类型或者对象上,并创建一个被通知的对象,分为:编译时织入、类加载时织入、执行时织入。(使切面和对象(模块功能)牵连起来)
Spring官方文档给出的解释:
Advice(通知)的类型(在切面某个特定连接点执行的动作)
前置通知(Before advice):在某连接点(join point)(某个功能方法开始执行前)之前执行的通知,但不能阻止连接点前的执行(除该方法外的其他方法的执行)(除非它抛出一个异常)。
返回后通知(After returning advice):在某连接点(方法)正常完成后执行的通知(将要执行的切面功能)。
抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知(将要执行切面的功能)。
后通知(After(finally)advice):当某连接点(方法)退出的时候执行的通知(切面将要执行的功能)(不论是正常返回还是异常退出都会执行的通知)。
环绕通知(Around Advice):包围一个连接点(join point)的通知(在整个方法的内部都有切面要执行的功能存在,不分前后)。
Spring框架中AOP的用途:
用途1:提供了声明式的企业服务(也可以是其他服务,例如互联网服务),特别是EJB(重量级框架)的替代服务的声明。
用途2:允许用户定制自己的方面(切面),以完成OOP(面向对象编程,模拟世界中行为和方式,可以理解为实现一个功能的顺序)与AOP(横切的方式,可以理解为各个功能之间横切的一种功能)的互补使用,可以实现自己横切的功能。
三、Spring中的AOP(Spring中AOP的实现方式以及特点)
特点1:纯java实现,无需特殊的编译过程(普通代码需要加载才能执行),不需要控制类加载器层次。可以更好的进行控制(使用类加载器应当谨慎,容易方法生ClassNotFound异常这种情况)。
特点2:目前只支持方法执行连接点(通知Spring Bean的方法执行),(在执行某方法时,才去执行切面的功能)。
特点3:SpringAOP不是为了提供最完整的AOP实现(尽管它非常强大);而是侧重于提供一种AOP实现和Spring IoC容器之间的整合,用于帮助解决企业应用中的常见问题。
特点4:SpringAOP不会与AspectJ(完整的、全面的AOP解决方案)竞争,也不会提供综合全面的AOP解决方案。
有接口和无接口的SpringAOP实现区别:(一个类是否实现了某个接口,例如一个ProductService接口,一个ProductServiceImpl实现了该接口,在这类上切入的切面就是有接口的AOP)
SpringAOP对于有接口的使用标准的JavaSE动态代理作为AOP代理,这使得任何接口(或者接口集)都可以被代理。
SpringAOP对于没有接口的实现类中使用CGLIB代理(如果一个业务对象并没有实现一个接口)
四、Schema-based 实现AOP(基于配置文件实现AOP)
五、API实现AOP(基于API实现AOP)
六、AspectJ实现AOP
查看全部 -
bean容器初始化
查看全部 -
<aop:declare-parents types-matching = "com.imooc.aop.shema.advice.biz.*(+)" implement-interface = "com.imooc.aop.shema.advice.Fit" default-impl = "com.imooc.aop.shema.advice.FitImpl"/> 对所有匹配到的类都增加一个方法实现,FitImpl,这里是所有匹配到的biz类都可以转为Fit类 >
查看全部 -
Bean管理的注解实现及例子
1、Classpath扫描与组件管理
定义:从Spring3.0开始,Spring JavaConfig项目提供很多特性,包括通过注解定义Bean,而不是使用XML。
@Component:通用型注解,可用于任何Bean。
@Repository:通常用于注解DAO类,即持久类。
@Service:通常用于注解Service类,即服务层。
@Controller:通常用于注解Controller,即控制层。
2、类的自动检测与注册Bean
定义:Spring可以检测到类上和属性上以及方法上的注解,可以通过注解进行实例化或注入。
3、<context:annotation-config/>
定义:基于XML配置,如果使用该标签,则在描述中添加约束。
<context:component-scan>:一般处理类上的注解,它的功能包含<context:annotation-config>的功能,比较常用。
<context:annotation-config>:一般处理实例化Bean的属性和方法的注解。
SpringXML配置过滤器作用:扫描特定包下的特定注解。
4、@Component,@Repository,@Service,@Controller
5、@Required
6、@Autowired
7、@Qualifier
8、@Resource
查看全部 -
关于AOP配置相关
查看全部
举报