Spring

本文详细介绍了Spring框架中的IoC容器管理机制,包括构造方法注入、属性注入等,并对比了不同注入方式的特点。此外,还深入探讨了Spring AOP的概念及应用场景,通过具体示例展示了如何利用AOP进行横切关注点的模块化。
摘要由CSDN通过智能技术生成

IOC

构造方法注入示例:

Client.java

package com.java.client;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.java.manager.UserManager;

public class Client {
	public static void main(String[] args) {
			
//		UserManager userManager = new UserManagerImpl(new UserDaoMysql());
//		userManager.addUser("张三", "123");
		
		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserManager userManager = (UserManager)factory.getBean("userManager");
		userManager.addUser("小三", "怎么的");
	}
}
applicationContext.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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<bean id="userDaoMysql" class="com.java.dao.UserDaoMysql"></bean>
	<bean id="userDaoOracle" class="com.java.dao.UserDaoOracle"></bean>
	
	<bean id="userManager" class="com.java.manager.UserManagerImpl">
		<constructor-arg ref="userDaoOracle"/>
	</bean>
	
</beans>
UserManager.java

public interface UserManager {
	public void addUser(String usernmae,String password);
}
UserManagerImpl.java
public class UserManagerImpl implements UserManager {

	private UserDao userDao;
	
	//构造方法赋值
	public UserManagerImpl(UserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public void addUser(String username, String password) {
		//之前由我们自己负责对象
		//UserDao userDao = new UserDaoMysql();

		userDao.addUser(username, password);
	}
}

UserDao.java
public interface UserDao {
	public void addUser(String username,String password);
}
UserDaoMysqlImpl.java
public class UserDaoMysql implements UserDao {

	@Override
	public void addUser(String username, String password) {
		System.out.println("-----------Mysql已存储-----------");
	}
}
UserDaoOracleImpl.java

public class UserDaoOracle implements UserDao {

	@Override
	public void addUser(String username, String password) {
		System.out.println("----------Oracle已存储-----------");
	}
}

构造方法注入与set方法注入区别:

set注入:
UserManagerImpl.java
public class UserManagerImpl implements UserManager {

	private UserDao userDao;

	@Override
	public void addUser(String username, String password) {
		userDao.addUser(username, password);
	}
	
	//set方法注入
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
}

applicationContext.xml

	<bean id="userDaoMysql" class="com.java.dao.UserDaoMysql"></bean>
	<bean id="userDaoOracle" class="com.java.dao.UserDaoOracle"></bean>
	
	<bean id="userManager" class="com.java.manager.UserManagerImpl">
		<property name="userDao" ref="userDaoMysql"/>
	</bean>
构造方法注入:
UserManagerImpl.java

public class UserManagerImpl implements UserManager {

	private UserDao userDao;
	
	//构造方法赋值
	public UserManagerImpl(UserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public void addUser(String username, String password) {
		userDao.addUser(username, password);
	}
}
applicationContext.xml

	<bean id="userDaoMysql" class="com.java.dao.UserDaoMysql"></bean>
	<bean id="userDaoOracle" class="com.java.dao.UserDaoOracle"></bean>
	
	<bean id="userManager" class="com.java.manager.UserManagerImpl">
		<constructor-arg ref="userDaoOracle"/>
	</bean>

属性注入:

Bean1.java

package com.java;

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

public class Bean1 {
	private String strValue;
	private int intValue;
	private List listValue;
	private Set setValue;
	private String[] arrayValue;
	private Map mapValue;
	
	// 此处省略  Setter  Getter 方法
	//		…………
}
applicationContext.xml

	<bean id="bean1" class="com.java.Bean1">
		<property name="strValue" value="小龙_你好"></property>
		
		<property name="intValue" value="88888"></property>
		
		<property name="listValue">
			<list>
				<value>list1</value>
				<value>list2</value>
			</list>
		</property>
		
		<property name="setValue">
			<set>
				<value>set1</value>
				<value>set2</value>
			</set>
		</property>
		
		<property name="arrayValue">
			<list>
				<value>array1</value>
				<value>array2</value>
			</list>
		</property>
		
		<property name="mapValue">
			<map>
				<entry key="k1" value="v1"></entry>
				<entry key="k2" value="v2"></entry>
			</map>
		</property>
	</bean>

日期格式注入 属性编辑器

Test.java

public class Test {
	public static void main(String[] args) {
		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
		Bean1 bean1 = (Bean1)factory.getBean("bean1");
		System.out.println(bean1.getDate());
	}
}
Bean1.java
public class Bean1 {

	private Date date;

	public Date getDate() {
		return date;
	}
	public void setDate(Date date) {
		this.date = date;
	}
}
UtilDateEditor.java

package com.java;

import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

//Date属性编辑器
public class UtilDateEditor extends PropertyEditorSupport{

	@Override
	public void setAsText(String text) throws IllegalArgumentException {
		System.out.println("----------属性编辑器---------");
		try {
			//配置格式
			Date date = new SimpleDateFormat("yyyy-MM-dd").parse(text);
			//注入属性
			this.setValue(date);
		} catch (ParseException e) {
			e.printStackTrace();
			throw new IllegalArgumentException("日期参数非法");
		}
	}
}
applicationContext.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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<bean id="customEditors" class="org.springframework.beans.factory.config.CustomEditorConfigurer">	
		<property name="customEditors">
			<map>
				<entry key="java.util.Date">
					<bean class="com.java.UtilDateEditor"></bean>
				</entry>
			</map>
		</property>
	</bean>
	
	<bean id="bean1" class="com.java.Bean1">
		<property name="date" value="2014-10-01"></property>
	</bean>
	
</beans>

减少配置量_将公共配置抽象

	<bean id="parentBean" abstract="true">
		<property name="id" value="100"></property>
		<property name="name" value="大龙"></property>
		<property name="sex" value="男"></property>
	</bean>
	
	<bean id="bean4" class="com.java.Bean4" parent="parentBean">
		<property name="age" value="18"></property>
	</bean>

AOP

  • Cross Cutting Concern
— 是一种独立服务,他会遍布在系统的处理流程之中
  • Aspect
— 对横切性关注点的模块化

  • Advice

— 对横切关注点的具体实现

  • Pointcut

— 他定义了Advice应用到哪些JoinPiont(方法)上,对Spring来说是方法调用

  • Weave

— 将Advice应用到Target Object上的过程叫织入,Spring支持的是动态织入

  • Target Object

— Advice被应用的对象

  • Proxy

— Spring AOP默认使用JDK的动态代理,它的代理是运行时创建,也可以使用CGLIB代理

  • Introduction

— 可以动态的为类添加方法

AOP示例(采用Annotation方式)

Demo.java

package com.java;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo {
	public static void main(String[] args) {
		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserManager userManager = (UserManager)factory.getBean("userManager");
		userManager.addUser("张三", "root");
	}
}
UserManager.java
package com.java;

public interface UserManager {
	public void addUser(String username,String password);
	public void delUser(int id);
	public String findUser(int id);
	public void modifyUser(int id,String username,String password);
}
UserManagerImpl.java

package com.java;

public class UserManagerImpl implements UserManager {

	@Override
	public void addUser(String username, String password) {
		System.out.println("添加用户成功");
	}

	@Override
	public void delUser(int id) {
		System.out.println("删除用户成功");
	}
	
	@Override
	public String findUser(int id) {
		System.out.println("查找用户成功");
		return "知道我是谁吗";
	}
	
	@Override
	public void modifyUser(int id, String username, String password) {
		System.out.println("修改用户成功");
	}
}
Check.java

package com.java;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class Check {
	/**
	 * 该方法无意义,标识作用(类似id)
	 */
	@Pointcut("execution(* add*(..))")
	private void addAddMethod(){}	
	
	/**
	 * 定义Advice,表示我们的Advice应用到
	 * 哪些Pointcut订阅的Joinpoint上
	 */
	@Before("addAddMethod()")
	private void check(){
		System.out.println("例行检查");
	}
}
applicationContext.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-3.0.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
	
	<!-- 启用AspectJ对Annotation的支持 -->
	<aop:aspectj-autoproxy/>
	
	<bean id="userManager" class="com.java.UserManagerImpl222"></bean>

	<bean id="check" class="com.java.Check"></bean>
	
</beans>

AOP示例(采用配置文件方式)

Check.java

package com.java;

public class Check {

	private void check(){
		System.out.println("例行检查");
	}
}
applicationContext.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-3.0.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
	
	
	<bean id="userManager" class="com.java.UserManagerImpl222"></bean>

	<bean id="check" class="com.java.Check"></bean>
	
	<aop:config>
		<aop:aspect id="checkAspect" ref="check">	
			<aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/>
			<aop:after method="check" pointcut-ref="addAddMethod"/>
		</aop:aspect>
	</aop:config>
	
</beans>

AOP 注解与配置文件   示意图


<!-- 以add开头的方法 -->
expression="execution(* add*(..))"

<!-- com.java包下所有类所有的方法 -->
expression="execution(* com.java.*.add*(..))"

可以采用Advice中添加一个JoinPoint参数获得调用参数

package com.java;

import org.aspectj.lang.JoinPoint;

public class Check {

	private void check(JoinPoint joinPoint){
		//获取参数列表的值
		for(int i=0;i<joinPoint.getArgs().length;i++){
			System.out.println(joinPoint.getArgs()[i]);
		}
		//获取调用的方法
		System.out.println(joinPoint.getSignature().getName());
		
		System.out.println("例行检查");
	}
}

JDK动态代理与CGLIB代理的区别?

  • JDK动态代理对实现了接口类进行代理 (spring默认)
  • CGLIB代理可以对类进行代理,主要对指定的类生成一个子类,因为是继承(类不能被final声明)
CGLIB:方法:

	<!-- 1、导入CGLIB包 -->
	
	<!-- 2、强制使用CGLIB代理 -->
	<aop:aspectj-autoproxy proxy-target-class="true"/>

Spring与Hibernate集成声明式事务(简单示例)

User.java

public class User {
	private int id;
	private String name;

	//Setter   Getter  省略
	
}

User.hbm.xml

<hibernate-mapping>
	<class name="com.domain.User">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>

	</class>
</hibernate-mapping>

Log.java
public class Log {
	private int id;
	//日志类别,
	private String type;
	private String detail;
	private Date date;

	//Setter   Getter  省略
	
}
Log.hbm.xml

<hibernate-mapping>
	<class name="com.domain.Log">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="type"/>
		<property name="detail"/>
		<property name="date"/>
	</class>
</hibernate-mapping>
Test.java
public class Test {
	public static void main(String[] args){

		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserManager userManager = (UserManager)factory.getBean("userManager");
		
		User user = new User();
		user.setName("大龙");
		try {
			userManager.addUser(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
UserManager.java
public interface UserManager {
	public void addUser(User user) throws Exception;
}
LogManager.java
public interface LogManager {
	public void addLog(Log log);
}
UserManagerImpl.java
public class UserManagerImpl extends HibernateDaoSupport implements UserManager{
	
	private LogManager logManager;

	public void setLogManager(LogManager logManager) {
		this.logManager = logManager;
	}

	@Override
	public void addUser(User user) throws Exception {
	
//			this.getHibernateTemplate().save(user);
			this.getSession().save(user);
		
			Log log = new Log();
			log.setType("操作日志");
			log.setDate(new Date());
			log.setDetail("我妹干坏事");
	
			logManager.addLog(log);	
	}
}
LogManagerImpl.java
public class LogManagerImpl extends HibernateDaoSupport implements LogManager{

	@Override
	public void addLog(Log log) {

		this.getSession().save(log);
		System.out.println("你的操作已记录");
	}
}
applicationContext.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:tx="http://www.springframework.org/schema/tx"  
    xmlns:p="http://www.springframework.org/schema/p"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
    http://www.springframework.org/schema/aop  
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">  

	<bean id="userManager" class="com.impl.UserManagerImpl">
		<property name="logManager" ref="logManager"></property>
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>

	<bean id="logManager" class="com.impl.LogManagerImpl">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>

	<!--                              Hibernate模板配置                                                                  -->
	
	<!-- 创建sessionFactory -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
	</bean>
	
	<!-- 配置事务管理器 -->
	<bean id="transationManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
	
	<!-- 配置哪些方法使用事务-->
	<aop:config>
		<aop:pointcut id="allManagerMethod" expression="execution(* com.manager.*.*(..))"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
	</aop:config>
	
	<!-- 配置事务传播特性   查询只读提升效率 -->
	<tx:advice id="txAdvice" transaction-manager="transationManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED"/>
			<tx:method name="del*" propagation="REQUIRED"/>
			<tx:method name="modify*" propagation="REQUIRED"/>
			<tx:method name="*" propagation="REQUIRED" read-only="true"/>
		</tx:attributes>
	</tx:advice>
</beans>
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC  
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
  
<hibernate-configuration>  
  
    <session-factory>  
  
        <!-- Database connection settings -->  
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>  
        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>  
        <property name="connection.username">root</property>  
        <property name="connection.password">root</property>  
  
        <!-- SQL dialect -->  
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>  
  
        <!-- Disable the second-level cache  -->  
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>  
  
        <!-- Echo all executed SQL to stdout -->  
        <property name="show_sql">true</property>  
  
        <property name="hbm2ddl.auto">update</property> 

        <mapping resource="com/domain/User.hbm.xml"/>  
        <mapping resource="com/domain/Log.hbm.xml"/>  

    </session-factory>  
  
</hibernate-configuration> 

Spring其他知识点:

Spring默认在创建工厂的时候,将配置文件中所有的对象实例化并且进行注入  但也可使用懒加载属性
lazy-init="true"


//工厂模式  一样使用
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml");


Spring bean的作用域
scope取值
singleton:默认  单例模式
prototype:多例模式  每次取出对象都不一样


根据名字自动装配、根据类型自动装配
default-autowire="byName" //查找配置文件id
default-autowire="byType" //查找配置文件class


Spring sessionFactory 的配置
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation"
value="file:src/hibernate.cfg.xml">
</property>
</bean>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值