Spring——IoC和Aop使用拓展

一、多种方式实现依赖注入

  1. 构造注入
  2. 设值注入
  3. p命名空间注入

1、构造注入:通过构造函数注入数据。

构造注入的优劣势:构造注入的时效性好,在对象实例化时就得到所依赖的对象,便于在对象的初始化时就得到所依赖的对象,便于在对象的初始化方法中使用依赖对象;但受限于方法重载的形式,使用灵活性不足。



	1
	张三
	123

2、设值注入:通过setter访问器注入数据。

设值注入的优劣势:设值注入使用灵活,但时效性不足,并且大量的setter访问器增加了类的复杂性。



	
	
	

3、p命名空间注入:Spring配置文件从2.0版本开始采用schema形式,使用不同的命名空间管理不同类型的配置,使得配置文件更具拓展性并且简化配置的工作量。

注意:使用p命名空间必须导入 xmlns:p="http://www.springframework.org/schema/p"


Spring并不倾向于某种注入方式,用户应该根据实际情况进行合理的选择。

 

二、处理不同类型的数据:

  • 特殊字符串处理
  • JavaBean
  • List
  • Array
  • Set
  • Map
  • Properties
  • 空字符串
  • null值

实体类:TestEntity.java

package entity;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class TestEntity {
    private String specialCharacter1; // 特殊字符值1
    private String specialCharacter2; // 特殊字符值2
    private User innerBean; // JavaBean类型
    private User userBean; // JavaBean类型
    private List list; // List类型
    private String[] array; // 数组类型
    private Set set; // Set类型
    private Map map; // Map类型
    private Properties props; // Properties类型
    private String emptyValue; // 注入空字符串值
    private String nullValue = "init value"; // 注入null值

    public User getUserBean() {
        return userBean;
    }

    public void setUserBean(User userBean) {
        this.userBean = userBean;
    }

    public void setSpecialCharacter1(String specialCharacter1) {
        this.specialCharacter1 = specialCharacter1;
    }

    public void setSpecialCharacter2(String specialCharacter2) {
        this.specialCharacter2 = specialCharacter2;
    }

    public void setInnerBean(User user) {
        this.innerBean = user;
    }

    public void setList(List list) {
        this.list = list;
    }

    public void setArray(String[] array) {
        this.array = array;
    }

    public void setSet(Set set) {
        this.set = set;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public void setProps(Properties props) {
        this.props = props;
    }

    public void setEmptyValue(String emptyValue) {
        this.emptyValue = emptyValue;
    }

    public void setNullValue(String nullValue) {
        this.nullValue = nullValue;
    }

    public void showValue() {
        System.out.println("特殊字符1:" + this.specialCharacter1);
        System.out.println("特殊字符2:" + this.specialCharacter2);
        System.out.println("内部Bean:" + this.innerBean.getUsername());
        System.out.println("userBean:" + this.userBean.getUsername());
        System.out.println("List属性:" + this.list);
        System.out.println("数组属性[0]:" + this.array[0]);
        System.out.println("Set属性:" + this.set);
        System.out.println("Map属性:" + this.map);
        System.out.println("Properties属性:" + this.props);
        System.out.println("注入空字符串:[" + this.emptyValue + "]");
        System.out.println("注入null值:" + this.nullValue);
    }
}

spring配置文件:springConfig.xml





	
		
		
	

	
	

		
		
			
		

		
		
			P&G
		

		
		
			
			
		

		
		
			
				
				
			
		

		
		
			
				足球
				篮球
			
		

		
		
			
				足球
				篮球
			
		

		
		
			
				足球
				篮球
			
		

		
		
			
				
					football
					足球
				
				
					basketball
					篮球
				
			
		

		
		
			
				足球
				篮球
			
		

		
		
			
		

		
		
			
		
	


junit测试:

@Test
public void testEntity(){
	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("springConfig.xml");
	TestEntity testEntity = (TestEntity)context.getBean("testEntity");
	testEntity.showValue();
}

测试结果:

Spring——IoC和Aop使用拓展_第1张图片

 

三 、使用注解实现IoC的配置

1、使用注解实现Bean组件的定义:

@Component:该注解与等效。

@Respository:该注解用于标注Dao类

@Service:该注解用于标注业务逻辑类

@Controller:该注解用于标注控制器类

2、使用注解实现Bean组件的装配:

@Autowired:该注解用于注入所依赖的对象。

@Autowired 采用按类型匹配的方式为属性自动装配合适的依赖对象,即容器会查找和属性类型相匹配的Bean组件,并自动为属性注入。

@Qualifier:该注解用于指定所需Bean的名字。

 

3、加载注解定义的Bean:

首先在spring配置文件中添加对context命名空间的声明,然后使用context命名空间下的component-scan标签扫描注解标注的类,base-package 属性指定了需要扫描的基准包(多个包逗号隔开)。


 

使用注解实现一个简单的IoC的配置

spring配置文件:springConfig.xml




        
	

数据访问层:userDaoImpl.java

package dao;

import org.springframework.stereotype.Repository;

@Repository("userDao")
public class UserDaoImpl implements UserDao {

}

业务逻辑层:userServiceImpl.java

package service;

import dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired
	@Qualifier("userDao")
	private UserDao userDao;

	@Override
	public void demo() {
		// TODO Auto-generated method stub
		System.out.println("userDao内存地址:" + userDao);
	}
}

junit测试:

@Test
public void testUserService() {
	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("springConfig.xml");
	UserServiceImpl userService = (UserServiceImpl)context.getBean("userService");
	userService.demo();
	}

测试结果:

 四 、使用注解定义切面

AspectJ是一个面向切面的框架,它拓展了Java语言,定义了AOP语法,能够在编译期间提供代码的织入,所以它有一个专门的编译器用来生产遵守字节编码规范的Class文件。

Spring通过集成AspectJ实现以注解的方式定义切面,大大减少了配置文件的工作量。此外因为Java的反射机制无法获取方法参数名,Spring还需要利用轻量级的字节码处理框架 asm(已集成在Spring Core 模块中)处理@AspectJ中所描述的方法参数名。

 

使用注解实现一个简单的AOP切面:

spring配置文件:springConfig.xml




	
	
	
	

业务逻辑类:Target.java

package service;

import org.springframework.stereotype.Component;

@Component("target")
public class Target {
	public void helloAop(String name) {
		System.out.println("hello,"+name);
	}

}

辅助增强类:AdviceTarget.java

package aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;

import java.util.Arrays;

@Aspect
public class AdviceTarget {

	@Pointcut("execution (* aop.Target.*(..))")
	private void anyMethod() {} // 声明一个切入点,anyMethod为切入点名称

	@Before("anyMethod()")
	public void before(JoinPoint jp) {
		System.out.println("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。方法入参:"+ Arrays.toString(jp.getArgs()));
	}
	@After("anyMethod()")
	public void after(JoinPoint jp) {
		System.out.println(jp.getSignature().getName()+"方法结束执行");
	}
	@AfterReturning(value = "anyMethod()",returning="result")
	public void afterReturning(JoinPoint jp,Object result) {
		System.out.println("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。方法返回值:"+result);
	}
	@AfterThrowing(value = "anyMethod()",throwing = "e")
	public void afterThrowing(JoinPoint jp,RuntimeException e) {
		System.out.println(jp.getSignature().getName()+"方法发生异常:"+e);
	}
}	

junit测试:

@Test
public void testTarget(){
	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("springConfig.xml");
	Target target = (Target)context.getBean("target");
	target.helloAop("world!");
}

测试结果:

Spring——IoC和Aop使用拓展_第2张图片

你可能感兴趣的:(Spring框架)