Spring——IoC和Aop使用拓展

版权声明:未经作者允许,禁止私自转载! https://blog.csdn.net/qq_42726314/article/details/82862985

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

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

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

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

<!-- 构造注入 -->
<bean id="user" class="entity.User">
	<constructor-arg><value>1</value></constructor-arg>
	<constructor-arg><value>张三</value></constructor-arg>
	<constructor-arg><value>123</value></constructor-arg>
</bean>

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

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

<!-- 设值注入 -->
<bean id="user" class="entity.User">
	<property name="username" value="张三"/>
	<property name="id" value="1"/>
	<property name="password" value="123"/>
</bean>

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

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

<!-- P命名空间实现属性注入 -->
<bean id="user" class="entity.User" p:id="1" p:password="123" p:username="张三"/>

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<String> list; // List类型
    private String[] array; // 数组类型
    private Set<String> set; // Set类型
    private Map<String, String> 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<String> list) {
        this.list = list;
    }

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

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

    public void setMap(Map<String, String> 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

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:aop="http://www.springframework.org/schema/aop"
	   xmlns:p="http://www.springframework.org/schema/p"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
">

<!-- 定义User对象,并指定id为user -->
	<bean id="user" class="entity.User">
		<property name="username" value="admin"/>
		<property name="password" value="admin"/>
	</bean>

	<!-- Spring 注入不同数据类型 -->
	<bean id="testEntity" class="entity.TestEntity">

		<!-- 1、特殊字符串处理方式1 字符串:P&G-->
		<property name="specialCharacter1">
			<value><![CDATA[P&G]]></value>
		</property>

		<!-- 2、特殊字符串处理方式2 -->
		<property name="specialCharacter2">
			<value>P&amp;G</value>
		</property>

		<!-- 3、引入其他Bean组件  -->
		<property name="innerBean">
			<!-- 引入user组件 -->
			<ref bean="user"></ref>
		</property>

		<!-- 4、使用内部Bean -->
		<property name="userBean">
			<bean class="entity.User">
				<property name="username" value="秋风抚水"/>
				<property name="password" value="123"/>
			</bean>
		</property>

		<!-- 5、注入集合类型的参数 -->
		<property name="list">
			<list>
				<value>足球</value>
				<value>篮球</value>
			</list>
		</property>

		<!-- 6、注入数组类型的参数 -->
		<property name="array">
			<list>
				<value>足球</value>
				<value>篮球</value>
			</list>
		</property>

		<!-- 6、注入Set类型的参数 -->
		<property name="set">
			<set>
				<value>足球</value>
				<value>篮球</value>
			</set>
		</property>

		<!-- 7、注入map类型的参数 -->
		<property name="map">
			<map>
				<entry>
					<key><value>football</value></key>
					<value>足球</value>
				</entry>
				<entry>
					<key><value>basketball</value></key>
					<value>篮球</value>
				</entry>
			</map>
		</property>

		<!-- 8、注入Properties类型的参数 -->
		<property name="props">
			<props>
				<prop key="football">足球</prop>
				<prop key="basketball">篮球</prop>
			</props>
		</property>

		<!-- 9、注入空字符串值 -->
		<property name="emptyValue">
			<value></value>
		</property>

		<!-- 10、注入null值 -->
		<property name="nullValue">
			<null/>
		</property>
	</bean>


</beans>

junit测试:

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

测试结果:

 

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

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

@Component:该注解与<bean id="user" class="entity.User"/>等效。

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

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

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

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

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

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

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

 

3、加载注解定义的Bean:

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

<!-- 扫描包中注解标注类 -->
<context:component-scan base-package="dao,service,entity"/>

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

spring配置文件:springConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context"
	   xmlns:aop="http://www.springframework.org/schema/aop"
	   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
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

        <!-- 扫描包中注解标注类 -->
	<context:component-scan base-package="dao,service,entity,aop"/>
</beans>

数据访问层: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

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context"
	   xmlns:aop="http://www.springframework.org/schema/aop"
	   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
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

	<!-- AOP代理 -->
	<aop:aspectj-autoproxy/>
	<bean id="target" class="aop.Target"/>
	<bean id="adviceTarget" class="aop.AdviceTarget"/>
</beans>

业务逻辑类: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!");
}

测试结果:

猜你喜欢

转载自blog.csdn.net/qq_42726314/article/details/82862985