—Spring IOC(控制反转)
作用:帮助我们创捷对象的,进行代码之间的解耦
IOC实现方式{
A、无参构造
<bean id="stu2" class="com.bjsxt.spring2.Student"></bean>
B、有参构造
<!--
Student stu3=new Student(18,zs,男);
注意
[1]name属性和形参的名称保持一致的
[2]形参的顺序不用和标签的顺序一致
[3]我们使用name属性进行调用
但是除了name属性还有index(从0)
type :数据类型
建议三者都写上即可
-->
<bean id="stu3" class="com.bjsxt.spring2.Student">
<!--<constructor-arg name="a" value="18"></constructor-arg>
<constructor-arg name="name" value="zs"></constructor-arg>
<constructor-arg name="sex" value="男"></constructor-arg>-->
<constructor-arg name="a" index="1" type="int" value="123"></constructor-arg>
<constructor-arg name="b" index="0" type="java.lang.String" value="456"></constructor-arg>
</bean>
C、工厂模式
设计模式:设计模式是为了解决某一类问题的产生
工厂模式就是批量生产对象的
<!-- Factory factory=new Factory();-->
<bean id="factory" class="com.bjsxt.spring3.Factory"></bean>
<!-- factory.getInstance("tea");-->
<bean id="be" factory-bean="factory" factory-method="getInstance">
<constructor-arg name="param" value="stu"></constructor-arg>
</bean>
<!--Factory.getInstance2('stu')-->
<bean id="be2" class="com.bjsxt.spring3.Factory" factory-method="getInstance2">
<constructor-arg name="param" value="stu"></constructor-arg>
</bean>
}
DI:依赖注入
作用:给创建好的全局属性或者对象进行赋值
DI注入方式{
A、有参构造
<bean id="cla" class="com.bjsxt.spring4.Clazz">
<constructor-arg name="cname" value="java1班"></constructor-arg>
<constructor-arg name="clazzno" value="507"></constructor-arg>
</bean>
<bean id="stu" class="com.bjsxt.spring4.Student">
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="name" value="zs"></constructor-arg>
<constructor-arg name="sex" value="男"></constructor-arg>
<constructor-arg name="clazz" ref="cla"></constructor-arg>
</bean>
B、set方法
<!--
name:对象的属性名
value和ref的使用场景
value: 如果注入的属性类型是基本数据类型(包含String)使用value
ref:如果注入的属性类型是对象这个时候使用ref
-->
<bean id="stu" class="com.bjsxt.spring4.Student">
<property name="name" value="lisi"></property>
<property name="sex" value="男"></property>
<property name="age" value="20"></property>
<property name="clazz" ref="cla"></property>
</bean>
C、自动注入
<!--
底层走的是set方法
byName:这个时候就会在当前的xml中寻找【bean的ID名称】和需要注入实体中的【属性名】一致,进行匹配注入
byType:这个时候就会在当前的xml中寻找【bean标签的类型】和需要注入实体中的【属性的类型】一致,进行匹配注入
底层走的是构造器
constructor:这个时候首先会根据[有参构造器的形参名]名称进行查找,如果名称没有一致的,在根据类型[有参构造器的类型]进行查找
需要注意:*在指定的类中必须提供合适的有参构造器才可以
-->
<bean id="stu" class="com.bjsxt.spring4.Student" autowire="constructor"></bean>
D、其他注入:
A、基本类型(String)
B、对象类型
C、数组
D、List
E、set
F、Map
<bean id="us" class="com.bjsxt.spring4.User">
<property name="arr">
<array>
<value>A</value>
<value>B</value>
<value>C</value>
</array>
</property>
<property name="li">
<list>
<value>A</value>
<value>B</value>
<value>C</value>
</list>
</property>
<property name="se">
<set>
<value>A</value>
<value>A</value>
<value>B</value>
<value>C</value>
</set>
</property>
<property name="map">
<map>
<entry>
<key><value>A</value></key>
<value>1</value>
</entry>
<entry>
<key><value>B</value></key>
<value>1</value>
</entry>
<entry>
<key><value>C</value></key>
<value>1</value>
</entry>
</map>
</property>
</bean>
}
—Spring AOP{面向切面编程
代理模式{静态代理 动态代理-[JDK代理、CGLIB代理]}
好处:增强代码可扩展性
jdk代理模式是必须有接口的操作
AOP作用:提升代码的扩展性 、进行了代码的解耦
AOP的实现方式{A、schema base B、aspectJ}
注意:
AOP的底层默认的使用是JDK代理 我们也可以手动的开始CGLib代理方式
<!-- cglib代理方式 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
AspectJ
[1]我们目前使用AOP的不足?
我们目前使用的schema Baes 实现的方式,发现了每一个通知都需要实现对应的接口,每一个接口中就是一个方法,这样的书写方式比较的麻烦的,我们想所有的方法都在一个类中书写就比较方便了。
[2]解决方式
Aspect J方式实现
我们发现 Aspect J的方式虽然可以把所有的通知都结合到一起,书写方便,但是获得切点中的参数和切点所在的类的时候比较的繁琐
[3]两种方式的使用场景
A、schema base :如果我们需要使用切点中的参数或者切点所在的类对象的时候
B、aspect J:就是简单的给切点增加通知的时候使用这个方式比较简单
通知代码
public class AspectJAdvice {
//前置通知方法
public void beforAd(JoinPoint joinPoint){
System.out.println("前置通知");
}
//后置通知方法
public void afterAd(){
System.out.println("后置通知");
}
//环绕通知方法
public Object aroundAd(ProceedingJoinPoint point) throws Throwable{
System.out.println("环绕通知--前");
Object o = point.proceed();
System.out.println("环绕通知--后");
return o;
}
//异常通知方法
public void throwsAd(){
System.out.println("异常通知");
}
}
配置代码
<bean id="us" class="com.bjsxt.pojo.User"></bean>
<!--配置通知类的对象-->
<bean id="aps" class="com.bjsxt.advice.AspectJAdvice"></bean>
<aop:config>
<aop:aspect ref="aps">
<aop:pointcut id="pt" expression="execution(* com.bjsxt.pojo.User.a())"></aop:pointcut>
<!--给切点增加对应的通知-->
<aop:before method="beforAd" pointcut-ref="pt"></aop:before>
<!--无论切点中方法是否有异常,这个后置通知都会执行-->
<aop:after method="afterAd" pointcut-ref="pt"></aop:after>
<!--只有切点中的方法没有异常的时候才会执行这个通知-->
<!--<aop:after-returning method="afterAd" pointcut-ref="pt"></aop:after-returning>
<aop:around method="aroundAd" pointcut-ref="pt"></aop:around>
<aop:after-throwing method="throwsAd" pointcut-ref="pt"></aop:after-throwing>
</aop:aspect>
</aop:config>
Spring 中声明式事务
给方法增加事务 就是给切点增加通知
切点:需要的方法
通知:事务
构成切面
代码实现:
<!--声明事务的对象-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="ds"></property>
</bean>
<tx:advice id="ad" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="login" />
</tx:attributes>
</tx:advice>
<!--通过配置切面的方式增加通知-->
<aop:config>
<aop:pointcut id="pt" expression="execution(* com.bjsxt.service.impl.AdminServiceImpl.*(..))"></aop:pointcut>
<aop:advisor advice-ref="ad" pointcut-ref="pt"></aop:advisor>
</aop:config>
–Spring 中注解的支持
创建对象 :@Component @Service @Controller
进行值得注入: @Resource @Autowired
<context:component-scan base-package="com.bjsxt.service.impl"></context:component-scan>
AspectJ的注解: @Aspect @Befor ..
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
声明式事务注解 @Transactional
<tx:annotation-driven></tx:annotation-driven>