控制反转(IoC:Inversion of Control ) 也称为依赖注入(DI:Dependency Injection )<br>
什么是依赖
A类中的方法中,实例化了B类的对象并调用其方法以完成特定的功能,我们就说A类依赖于B类<br>
什么是高度耦合
程序不具备优良的可扩展性,可维护新,依赖较多,称之为高度耦合
依赖注入/反转控制的作用
用来降低程序代码之间的耦合度
所需要的jar包
commons-logging
spring-beans
spring-context
spring-core
spring-expression
applicationContext.xml配置文件
<bean>标签
使用<bean>标签来定义Bean(可以称为组件,实际就是java类)的实例
id属性:表示Bean实例的名称
class属性:表示Bean实例的类型
<property>标签
使用<property>标签给属性赋值
name属性:对应java类当中的属性
value属性:只能赋值基本类型和String类型,类类型,不可以
ref属性:用于类类型,已注入定义好的Bean
SpringBean属性赋值是通过调用属性的setter方法实现的,这种做法称为设值注入
<constructor-arg>标签
构造注入
一个<constructor-arg>元素表示构造方法的一个参数,且使用时不区分顺序。
当构造方法的参数出现混淆,无法区分是,可以通过index属性制定该参数的位置索引。位置从0开始
type属性可以用来制定参数类型
<context:component-scan base-package="com" />
扫描注解标注类
核心对象
ApplicationContext是一个接口,负责读取Spring 配置文件,管理对象加载,生成,维护Bean和Bean对象之间的依赖关系,负责Bean的生命周期等.
ClassPathXmlApplicationContext是ApplicationContext接口的实现类,用于从classpath路径中读取Spring配置文件
IOC/DI注解
@Compoent("userDao")
作用与在applicationContext.xml配置文件中配置编写了<bean id="userDao" class="dao.UserDao">
@Repository("") 用于标注Dao类
@Service("")用于标注业务类
@Controller("")用于标注控制器类
@Autowrited
实现Bean的装配
使用这个注解,可以省略setter方法
component-scan标签扫描注解标注类,base-package属性制定需要扫描的包,多个用逗号隔开
@Resource注解于@Autowrited相似
构造注入
<bean id="userDao" class="dao.impl.UserDaoImpl"><bean id="userService" class="service.impl.UserServiceImpl"><br></bean></bean>
一个元素表示构造方法的一个参数,且使用时不区分顺序
通过元素的index 属性可以指定该参数的位置索引,位置从0 开始。
元素还提供了type 属性用来指定参数的类型,避免字符串和基本数据类型的混淆。
面向切面编程(AOP:Aspect Oriented Programming)<br>
所谓面向切面编程,是一种通过预编译和运行期动态代理的方式实现在不修改源代码的情况下给程序动态添加功能的技术
AOP的目标:让我们可以“专心做事”
AOP原理<br>
将复杂的需求分解出不同方面,将散布在系统中的公共功能集中解决
采用代理机制组装起来运行,在不改变原程序的基础上对代码段进行增强处理,增加新的功能<br>
AOP相关术语<br>
增强处理(Advice)
前置增强<br>
后置增强<br>
环绕增强、异常抛出增强、最终增强等类型<br>
前置增强<br>
后置增强<br>
环绕增强、异常抛出增强、最终增强等类型<br>
切入点(Pointcut)<br>
连接点(Join Point)<br>
切面(Aspect)<br>
目标对象(Target object)
AOP代理(AOP proxy)
织入(Weaving)
举例1,使用AOP 实现日志输出
(1)在项目中添加springAop相关jar包
aopalliance
aspectjweaver
spring-aop
(2)编写前置增强和后置增强实现日志功能
public class UserServiceImpl {
<br> public void addUser(){
<br> System.out.println("在UserServiceImpl中执行了addUser方法");
<br> }
<br>} <br>
public class UserServiceLogger {
<br> private static final Logger log =Logger.getLogger(UserServiceLogger.class);
<br> /**
<br> * 代表前置增强方法
<br> * @param jp
<br> */
<br> public void before(JoinPoint jp){
<br> log.info("调用了:"+jp.getTarget()+"的"+jp.getSignature().getName()
<br> +"方法。方法入参:"+Arrays.toString(jp.getArgs())
<br> );
<br> }
<br> public void afterReturning(JoinPoint jp,Object result){
<br> log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。返回值是:"+result);
<br>
<br> }
<br>}
(3)编写Spring配置文件,对业务方法进行增强处理
<bean id="userService" class="com.bdqn.service.UserServiceImpl"></bean><aop:config><aop:pointcut expression="execution(public void addUser())" <br=""><bean id="userService" class="com.bdqn.service.UserServiceImpl"></bean><br><bean></bean><bean id="userServiceLogger" class="com.bdqn.aop.UserServiceLogger"></bean><br><aop:config><br> <aop:pointcut expression="execution(public void addUser())"<br> id="pointcut" /><br> <aop:aspect ref="userServiceLogger"><br> <aop:before method="before" pointcut-ref="pointcut" /><br> <aop:after-returning method="afterReturning"<br> pointcut-ref="pointcut" returning="result" /><br> </aop:aspect><br></aop:config><br><br></aop:pointcut></aop:config>
(4)编写代码,调用
public static void main(String[] args) {
<br> // TODO Auto-generated method stub
<br> ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
<br> UserServiceImpl userService = (UserServiceImpl)app.getBean("userService");
<br> userService.addUser();
<br> }
举例2,使用注解标注切面