Spring-注解&代理模式&AOP
依赖注入
构造参数注入
根据构造器参数的顺序(索引)
<bean id="MyBean" class="cn.itsource._01_.MyBean">
<constructor-arg index="0" value="666" />
<constructor-arg index="1" value="张二娃" />
</bean>
根据构造器参数的名称
<bean id="MyBean" class="cn.itsource._01_.MyBean">
<constructor-arg name="id" value="1" />
<constructor-arg name="name" value="张三娃" />
</bean>
根据构造器的类型注入
<!-- 按照类型注入,必须一一对应,不能有重复的类型-->
<bean id="MyBean" class="cn.itsource._01_.MyBean">
<constructor-arg type="java.lang.Long" value="1" />
<constructor-arg type="java.lang.String" value="张四娃" />
</bean>
参数是自己对象
先在配置文件bean外面定义好
<bean id="otherBean" class="cn.itsource._01_.OtherBean"/>
<bean id="MyBean" class="cn.itsource._01_.MyBean">
<constructor-arg value="1" />
<constructor-arg value="张五娃" />
<constructor-arg ref="otherBean"/>
</bean>
使用一个内部的Bean完成(不需要加id)
<bean id="MyBean" class="cn.itsource._01_.MyBean">
<constructor-arg value="1" />
<constructor-arg value="张六娃" />
<constructor-arg>
<bean class="cn.itsource._01_.OtherBean"/>
</constructor-arg>
</bean>
集合数组属性注入
数组
简写
<property name="arrays" value="A,B,C" />
完整写法
<property name="arrays">
<array>
<value>xxx</value>
<value>yyy</value>
<value>zzz</value>
</array>
</property>
集合list和set
<property name="list">
<list>
<value>xxx</value>
<value>aaa</value>
<value>bbbb</value>
</list>
set无序不可重复
</property>
<property name="set">
<set>
<value>xxx</value>
<value>aaa</value>
<value>bbbb</value>
</set>
</property>
配置一个Properties对象
简单,不支持中文
<property name="props1">
<value>
Jpa.dialect=org.Jpa.dialect.HSQLDialect
Jpa.driverClassName=com.mysql.jdbc.Driver
</value>
</property>
支持中文
<property name="props2">
<props>
<prop key="Jpa.dialect">org.Jpa.dialect.HSQLDialect</prop>
<prop key="Jpa.driverClassName">com.mysql.jdbc.Driver中文 </prop>
</props>
</property>
全注解配置
配置context命名空间
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" *xmlns:context="http://www.springframework.org/schema/context"*
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.xsd
*http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd*">
注解配置bean的名称
完成之后,大家注意,现在的配置还有一个问题,比如说我按真实情况来一个Dao接口,然后 这个接口有两个实现,现在就会出问题
IUserDao (UserJdbcDaoImpl/UserJpaDaoImpl)
而我们声明的时候就是使用了IUserDao 此时会就出错:因为Spring不知道你用的是哪一个dao的实现
为dao生成的bean加上名称,我们在调用的时候确定名称即可
1、@Repository("userJdbcDao")
2、@Autowired @Qualifier("userJdbcDao")
3、@Resource(name="userJpaDao")(一般不用)
Spring的AOP
AOP术语
连接点(Joinpoint):程序执行的某一个特定位置,如类初始前后,方法的运行前后。而 Spring只支持方法的连接点。
切点(Pointcut):切点可以定位到相应的连接点,一个切点可以定位多个连接点。
增强(Advice):又被称为通知,完成逻辑的增强。
目标对象(Target):增强逻辑织入的目标类。
引介(Introduction):特殊的增强,为类添加一些属性和方法。
织入(Weaving): 将增强添加到目标类的具体连接点上的过程。Spring使用动态代理织入。
代理(Proxy):一个类(原类)被织入增强(逻辑)后,就产生一个结果类,称为代理类。
切面(Aspect):由切点和增强组成
AOP联盟:众多开源AOP项目的联合组织,该组织定义了一套规范描述AOP标准。现在大部分的 AOP实现都是使用AOP实现的标准。
Spring实现AOP的方案
Spring实现Aop有两种方案:JDK与CGLIB
目标对象实现了接口自动选择JDK否则CGLIB
Xml版实现AOP
添加aop命名空间
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
增强(通知)
<aop:config>
<aop:pointcut expression="execution(* cn.itsource.aop.I*Service.*(..))" id="pointcut" />
<aop:aspect ref="txManager">
<!-- 前置通知 -->
<aop:before method="begin" pointcut-ref="pointcut"/>
<!-- 后置通知 -->
<aop:after-returning method="commit" pointcut-ref="pointcut"/>
<!-- 异常通知 -->
<aop:after-throwing method="rollback" pointcut-ref="pointcut"/>
<!-- 最终通知 -->
<aop:after method="close" pointcut-ref="pointcut" />
</aop:aspect>
</aop:config>
环绕增强
<aop:around method="around" pointcut-ref="pointcut" />
public void around(ProceedingJoinPoint joinPoint){
//System.out.println(joinPoint.getTarget()); //调用的类
//System.out.println(Arrays.asList(joinPoint.getArgs()));//参递的参数
//System.out.println(joinPoint.getSignature()); //方法签名
Object object = null;
try {
begin();
joinPoint.proceed(); //执行相应的代码
commit();
} catch (Throwable e) {
rollback(e);
}finally{
close();
}
}
全注解实现aop
配置文件
<context:component-scan base-package=“cn.itsource.aopanno” />
<aop:aspectj-autoproxy />
事务管理器
@Component
@Aspect //AOP的类注解
public class TxManager {
//设置切点
@Pointcut("execution(* cn.itsource.aopanno.I*Service.*(..))")
public void pointcut(){}
//前置通知
@Before("pointcut()")
public void begin(){
System.out.println("开启事务....");
}
//后置通知
@AfterReturning("pointcut()")
public void commit(){
System.out.println("提交事务...");
}
//异常通知
@AfterThrowing(pointcut="pointcut()",throwing="e")
public void rollback(Throwable e){
System.out.println("回滚事务....");
System.out.println(e.getMessage());
}
//最终通知
@After("pointcut()")
public void close(){
System.out.println("关闭资源....");
}
}
环绕通知方法:
//温馨提醒:如果要使用环绕通知的话,把其它几个通知的注解去掉(不然会出现重复)
@Around("pointcut()")
public void around(ProceedingJoinPoint joinPoint){
try {
begin();
joinPoint.proceed(); //执行相应的代码
commit();
} catch (Throwable e) {
rollback(e);
}finally{
close();
}
}