《spring注解配置spring》 《spring中的aop》
其中导包环节和约束环节这里不做讲解,因为现在项目基本都为maven
且公司一般都不会断网开发。所以可以忽略这两个
注解配置:
1.导包
2.约束
3.在配置文件中配置
开启注解配置
指定扫描该包下的所有注解,包括子包
<context:component-scan base-package=“xxx.xxx包下”></context:component-scan>
4.在类中进行注解配置
=======================================
将对象注解到容器中 (定义在类上
@Component(“自定义名称”)
为了区分层与层之间,也就是不让controller和service,dao之间都使用这个注解,
@Controller(“自定义名称”) web
@Service(“自定义名称”); service
@Repository(“自定义名称”) dao
如:
@Service(“Xxservice”)
public class XxserviceImpl{
}
ps:
@Service(“Xxservice”)==< bean name=“Xxservice” class=“XxserviceImpl的全类名” />
==== ===================================
修改对象的作用范围 (定义在类上
@Scop(“singleton|prototype”) 单例|多例
如:
@Scop(“prototype”)
public class XxserviceImpl{
}
ps:
什么时候使用多例?什么时候使用单例?
一般像用到strtus2时,因为strtus2是以类为单位,每次请求过来的时候都会创建一个新的类
和springmvc不一样,springmvc是以方法为单位的,若在配合strtus2不声明多例的话,那就意味改变了strtus2的架构,那就会出现很多问题,
== =====================================
值注入类型 (定义在属性上|set方法上
直接写在属性上破坏了对象的封装性,采用的是反射的Field
@Value(“张三”)
如:
@Value(“张三”) //破坏封装性
private String str;
@Value(“张三”)//建议使用 (但我不接受他们的建议,除非公司规定
public String setStr(){
}
引用类型注入
@Autowired//自动装配,缺点:若匹配到多个相同类型的无法确定具体植入哪一个
@Qualifier(“名称”)使用@Qualifier告诉spring自动装配的是那个名称的对象
前俩个可以混合进行使用,但不推荐
@Resource(name=“名称”)推荐使用,手动注入,指定注入那个名称的对象
=======================================
初始化方法&销毁方法
@PostConstrue (方法上
@PreDestory (方法上
======================================
spring与junit整合
1.导入需要的包
2.配置注解
@RunWith(SpringJunit4ClassRuner.class) 帮我们创建容器 (定义在类上
@ContextConfiguration(“xxxx.xml”)指定哪个配置文件 (定义在类上
好处:无需每次测试都创建容器,在类中可以写多个不同的方法对应测试
========================================
aop思想:横向重复,纵向抽取,比如:解决乱码,事务管理,拦截器(参数赋值
spring中的aop思想体现为:能够为我们生成代理对象
spring使用了:动态代理+cglib代理 ps:这里我们只需要知道使用的代理技术
动态代理(优先:
被代理对象必须要实现接口,才能产生代理对象.如果没有接口将不能使用动态代理技术
cglib代理(没有接口情况:
第三方代理技术,可以对任何对象进行代理,除了被final修饰的类,代理原理是对象目标对象进行继承代理
========================================
aop的demo简单看下帮助理解
1.导包
2.目标对象:
public class AaaServiceImpl implement AaaService{
public void save(){
syso("aaa");
}
public void update(){
syso("bbb");
}
}
3.准备通知(自定义增强代码
public class Utis{
//前置通知
|--目标方法执行前调用
//后置通知
|--目标方法调用后调用(异常情况下不调用
//环绕通知
|--目标方法前后都会调用
//异常拦截通知
|--若出现异常将被调用
//后置通知
|--目标方法后调用,(异常情况照样调用
//前置通知
public void before(){
syso(目标方法前执行);
}
//后置
public void afterReturning(){
syso(目标方法后执行,发生异常将不被执行);
}
//环绕 //该方法较为特殊,参数中为目标的原始方法,需要手动调用,syso表示调用方法前后的操作
public Object around(ProceedingJoinPoint pjp)throw 异常{
syso(目标方法前执行);
Object po = pjp.proceed();//调用目标方法
syso(目标方法后执行);
return po;
}
//异常通知
public void afterException(){
syso(异常后被执行);
}
//后置通知
public void after(){
syso(目标方法后执行);
}
}
4.使用配置文件将通知织入目标对象中
applictionContext.xml:
< !–准备工作,导入aop约束(命名空间–>
< !–1.配置目标对象–>
< bean name=“userService” class="">
< !–2.配置通知对象–>
< aop:config>
<!–配置切入点
切入表达式:* xx.xxx包下.serviceImpl.(…)
上面这一坨表示:
*:为任意返回值,包括void
xx.xxx包下:哪个包下
*serviceImpl:类的前缀名任意,后面只要是serviceImpl结尾
:任何方法,
(…):任何参数
xx.xxx包下如果再加个“.”表示包含子包 如: xx.xxx包下…serviceImpl.(…)
ps:
连接起来就是,任何返回值的具体包下的任何方法只要后缀是serviceImpl的任何方法
-->
<aop:pointcut expression="execution(* xx.xxx包下.*serviceImpl.*(..))" id="pc"/>
<aop:aspect ref="myXXXX">
<!--指定通知类中的方法名称为before为前置通知,
其中pointcut-ref="pc",对应到上面的切点表达式,
该切点表达式范围内的所有方法都会被影响
-->
<aop:before method="before" pointcut-ref="pc" />
<!--后置异常情况不执行-->
<aop:after-returning method="afterReturning" pointcut-ref="pc"/>
<!--环绕-->
<aop:around method="around" pointcut-ref="pc"/ >
<!--异常-->
<aop:after-throwing method="afterException" pointcut-ref="pc"/ >
<!--后置-->
<aop:after method="after" pointcut-ref="pc"/ >
</aop:aspect>
</aop:config>
5.进行测试
可以获取目标对象进行方法调用,会发现与原来方法执行出来的东西不一样,
不再打印aa和bb了,
在调用目标方法的时候,通知对象中定义的方法会相应进行执行。也就是说
配置spring通知后,调用目标方法的时候,其实也调用到了通知对象中的方法,
======================================================
注解方式
1.导包,
2.准备目标对象(同上
将目标对象和通知对象配置到容器(注解或配置文件都ok
3.准备通知对象
@Aspect //表示该类是一个通知类
public class Utis{
//该方法将冗余部分进行抽取,第一个方法
@Pointcut(“execution(* xx.xxx包下.serviceImpl.(…))”)
public void pc(){}
//前置通知
@Before("Utis.pc()") //指定该方法是前置通知,并指定切入点
public void before(){
syso(目标方法前执行);
}
//后置
@AfterReturning("execution(* xx.xxx包下.*serviceImpl.*(..))")
public void afterReturning(){
syso(目标方法后执行,发生异常将不被执行);
}
//环绕 //该方法较为特殊,参数中为目标的原始方法,需要手动调用,syso表示调用方法前后的操作
@Around("execution(* xx.xxx包下.*serviceImpl.*(..))")
public Object around(ProceedingJoinPoint pjp)throw 异常{
syso(目标方法前执行);
Object po = pjp.proceed();//调用目标方法
syso(目标方法后执行);
return po;
}
//异常通知
@AfterException("execution(* xx.xxx包下.*serviceImpl.*(..))")
public void afterException(){
syso(异常后被执行);
}
//后置通知
@After("execution(* xx.xxx包下.*serviceImpl.*(..))")
public void after(){
syso(目标方法后执行);
}
}
demo的总结:无非就是将通知(增强代码)织入到我们想要变强的目标对象中去,
使得原来的目标对象的方法具备了通知(增强的代码)使其比原来的
代码更加强大!其中在织入通知(增强的代码)后,原来的目标对象
就成为了代理对象。