赞
踩
为了编写时有一些提示或自动生成一些配置信息,需要增加插件:spring tool suite (sts)
新建名为 applicationContext.xml 的 Spring Bean Configuration File<!-- 该文件中产生的所有对象,被Spring放入了一个称之为SpringIOC容器的地方 -->
<!-- id:唯一标识符 class:指定类型 -->
<bean id="student" class="org.lanqiao.entity.Student">
<!--
property:该class所代表的类的属性
name:属性名
value:属性值
-->
<property name="stuNo" value="1"></property>
<property name="stuName" value="ls"></property>
<property name="stuAge" value="19"></property>
</bean>
//Spring上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//执行从SpringIOC容器中获取一个id为student的对象
Student student = (Student)context.getBean("student");
System.out.println(student.toString());
IOC (控制反转) 也可以称之为DI (依赖注入):
控制反转:将 创建对象,属性值的方式 进行了翻转,从 new,setXxx() 翻转为了从 SpringIOC容器 getBean()IOC容器赋值:
①如果是 简单类型 ,使用 value ;context.getBean(需要获取的bean的id值)
【 通过setXxx() 赋值,默认使用的set方法;依赖注入底层时通过 反射 实现的 】
<bean id="teacher" class="org.lanqiao.entity.Teacher">
<!-- 通过set方式赋值 -->
<property name="name" value="zs"></property>
<property name="age" value="20"></property>
</bean>
<bean id="course" class="org.lanqiao.entity.Course">
<!-- 通过set方式赋值 -->
<property name="courseName" value="java"></property>
<property name="courseHour" value="200"></property>
<!-- 将teacher对象注入到course对象中 -->
<property name="teacher" ref="teacher"></property>
</bean>
public static void testDI() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Course course = (Course)context.getBean("course");
course.showInfo();
}
【通过 构造方法 赋值】
<bean id="teacher" class="org.lanqiao.entity.Teacher">
<!-- 通过构造器赋值 -->
<constructor-arg value="李四"></constructor-arg>
<constructor-arg value="30"></constructor-arg>
</bean>
<bean id="course" class="org.lanqiao.entity.Course">
<!-- 通过构造器赋值 (参数顺序不一致,可通过index,name,type等指定参数)-->
<constructor-arg value="C语言"></constructor-arg>
<constructor-arg value="150"></constructor-arg>
<constructor-arg ref="teacher"></constructor-arg>
</bean>
public static void testDI() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Course course = (Course)context.getBean("course");
course.showInfo();
}
【引入p命名空间】
也可以直接在 appicationContext.xml 的头文件中添加:
xmlns:p="http://www.springframework.org/schema/p"
<bean id="teacher" class="org.lanqiao.entity.Teacher" p:age="25" p:name="王五">
</bean>
<bean id="course" class="org.lanqiao.entity.Course" p:courseName="Python" p:courseHour="120" p:teacher-ref="teacher">
</bean>
public static void testDI() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Course course = (Course)context.getBean("course");
course.showInfo();
}
【set,list,数组各自都有自己的标签< set >< list >< array > ,但也可以混着用,例如set也可以用< list >< array >】
<!-- 各种集合类型的属性注入 --> <bean id="CollectionDemo" class="org.lanqiao.entity.CollectionDemo"> <!-- 列表类型 --> <property name="listElement"> <list> <value>java1</value> <value>html1</value> <value>php1</value> </list> </property> <!-- 数组类型 --> <property name="arrayElement"> <array> <value>java2</value> <value>html2</value> <value>php2</value> </array> </property> <!-- set 类型 --> <property name="setElement"> <set> <value>java3</value> <value>html3</value> <value>php3</value> </set> </property> <!-- map 类型 --> <property name="mapElement"> <map> <entry> <key> <value>111</value> </key> <value>java4</value> </entry> <entry> <key> <value>222</value> </key> <value>html4</value> </entry> <entry> <key> <value>333</value> </key> <value>php4</value> </entry> </map> </property> <!-- properties 类型 --> <property name="propertiesElement"> <props> <prop key="555">java5</prop> <prop key="666">html5</prop> <prop key="777">php5</prop> </props> </property> </bean>
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
CollectionDemo collectionDemo = (CollectionDemo)context.getBean("CollectionDemo");
System.out.println(collectionDemo.toString());
【自动装配虽然可以减少代码量,但是会降低程序的可读性,使用时需要谨慎。】
<bean id="teacher" class="org.lanqiao.entity.Teacher" p:age="25" p:name="王五">
</bean>
<!-- byName 按id自动装配course的teacher对象-->
<bean id="course" class="org.lanqiao.entity.Course" autowire="byName">
<property name="courseName" value="zs"></property>
<property name="courseHour" value="20"></property>
</bean>
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Course course = (Course)context.getBean("course");
course.showInfo();
① byName: 自动寻找:其他bean的id值=该Course类的属性名(例:course 中的 teacher)
② byType: 其他bean的类型(class) 是否与 该Course类的ref属性类型一致 (注意,此种方式 必须满足:当前Ioc容器中 只能有一个Bean满足条件 )
③ constructor: 其他bean的类型(class) 是否与 该Course类的构造方法参数 的类型一致;此种方式的本质就是byType
通过注解的形式 将bean以及相应的属性值 放入ioc容器
(1) 在appicationContext.xml 的头文件中添加:
xmlns:context="http://www.springframework.org/schema/context"
(2) 在appicationContext.xml 的中添加:
<context:component-scan base-package="org.lanqiao.entity"></context:component-scan>
@Component细化:
① dao层注解:@Repository
② service层注解:@Service
③ 控制器层注解:@Controller
通过事务 使方法 要么全成功、要么全失败
xmlns:tx="http://www.springframework.org/schema/tx"
<tx:annotation-driven transaction-manager="txManager" />
从下往上补全:
<!-- 配置数据库相关 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.jdbc.cj.mysql.driver"></property> <property name="url" value="jdbc:mysql://127.0.0.1:3306/jdbc?serverTimezone=UTC"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> <property name="maxActive" value="10"></property> <property name="maxIdle" value="6"></property> </bean> <!-- 配置事务管理器txManager --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 增加对事务的支持 --> <tx:annotation-driven transaction-manager="txManager" />
将需要 成为事务的方法 前增加注解:
@Transactional(readOnly=false,propagation=Propagation.REQUIRED)
① aopaliance.jar
② aspectjweaver.jar
public class XmlAdvice {
public void before(){
System.out.println("这是前置通知...");
}
public void after(){
System.out.println("这是后置通知...");
}
}
public interface IStudentService {
public void addStudent();
public void deleteStudent();
}
public class StudentServiceImpl implements IStudentService{
@Override
public void addStudent() {
System.out.println("添加学生....");
// int x = 5/0; //异常:测试异常通知
}
@Override
public void deleteStudent() {
System.out.println("删除学生");
}
}
xmlns:aop="http://www.springframework.org/schema/aop"
<!-- 注册bean -->
<bean id="studentService" class="org.lanqiao.service.impl.StudentServiceImpl"></bean>
<bean id="xmlAdvice" class="org.lanqiao.aop.XmlAdvice"></bean>
<!-- 指定切点 -->
<aop:config>
<aop:pointcut expression="execution(public void org.lanqiao.service.impl.StudentServiceImpl.*(..))" id="pointcut"/>
<!-- 指定切面 -->
<aop:aspect ref="xmlAdvice">
<!-- 指定前置通知 -->
<aop:before method="before" pointcut-ref="pointcut"/>
<!-- 指定后置通知 -->
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
public static void testAOP() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
IStudentService studentService = (IStudentService)context.getBean("studentService");
studentService.addStudent();
studentService.deleteStudent();
}
public Object around(ProceedingJoinPoint point) { Object result = null; try{ System.out.println("这是环绕通知实现的[前置通知]..."); result = point.proceed(); //执行目标方法,addStudent() System.out.println("这是环绕通知实现的[后置通知]..."); }catch(Throwablee){ System.out.println("这是环绕通知实现的[异常通知]..."); e.printStackTrace(); } return result; }
<!-- 注册bean -->
<bean id="studentService" class="org.lanqiao.service.impl.StudentServiceImpl"></bean>
<bean id="xmlAdvice" class="org.lanqiao.aop.XmlAdvice"></bean>
<aop:config>
<!-- 指定切点 (StudentService中的所有方法) -->
<aop:pointcut expression="execution(public void org.lanqiao.service.impl.StudentServiceImpl.*(..))" id="pointcut"/>
<!-- 指定切面 -->
<aop:aspect ref="xmlAdvice">
<!-- 指定环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
③ 测试代码:**
public static void testAOP() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
IStudentService studentService = (IStudentService)context.getBean("studentService");
studentService.addStudent();
}
④ 运行结果:**
① aopaliance.jar
② aspectjweaver.jar
与 xml 不同之处: 使用注解注册bean
@Service("studentService") //等价于<bean id="studentService"
StudentServiceImpl :
@Service("studentService") //等价于<bean id="studentService" class="org.lanqiao.service.impl.StudentServiceImpl">
public class StudentServiceImpl implements IStudentService{
@Override
public void addStudent() {
System.out.println("添加学生....");
int x = 5/0; //异常:测试异常通知
}
}
与 xml 不同之处:
//使用注解注册bean
@Component("xmlAdvice")
//指定切面
@Aspect //通知
//指定环绕通知(指定切点)
@Around("execution(public * addStudent())")
XmlAdvice.java
@Component("xmlAdvice") //等价于<bean id="xmlAdvice" class="org.lanqiao.aop.XmlAdvice"> @Aspect //通知 public class XmlAdvice { @Around("execution(public * addStudent())") public Object around(ProceedingJoinPoint pj) { Object result = null; try{ System.out.println("这是环绕通知实现的前置通知"); result = pj.proceed(); //执行目标方法:addStudent() System.out.println("这是环绕通知实现的后置通知"); }catch(Throwable e){ System.out.println("这是环绕通知实现的异常通知"); System.out.println("异常类型:" + e.getMessage().toString()); } return result; } }
xmlns:aop="http://www.springframework.org/schema/aop"
<!-- 扫描包 -->
<!-- 扫描 studentService,xmlAdvice 这两个bean -->
<context:component-scan base-package="org.lanqiao.aop , org.lanqiao.service"></context:component-scan>
<!-- 开启 @aspectj 的自动代理支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
public static void testAOP() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
IStudentService studentService = (IStudentService)context.getBean("studentService");
studentService.addStudent();
}
order=1 值越小 优先级越高 (此时先执行后退出)
@Component("Advice")
@Aspect //指定切面
@Order(1) //值越小 优先级越高
public class Advice {
@Before("execution(public * addStudent())") //指定切点
public void before() {
System.out.println("这是 切面Advice 的前置通知");
}
@After("execution(public * addStudent())") //指定切点
public void after() {
System.out.println("这是 切面Advice 的后置通知");
}
}
@Order(3) 值越小 优先级越高 (此时后执行先退出)
@Component("xmlAdvice") //等价于<bean id="xmlAdvice" class="org.lanqiao.aop.XmlAdvice">
@Aspect //通知
@Order(3) //值越小 优先级越高
public class XmlAdvice {
@Before("execution(public * addStudent())") //指定切点
public void before() {
System.out.println("这是 切面XmlAdvice 的前置通知....");
}
@After("execution(public * addStudent())")
public void after() {
System.out.println("这是 切面XmlAdvice 的后置通知....");
}
}
思路:当服务启动时(tomcat),通过监听器将SpringIOC容器初始化一次(该监听器 spring-web.jar已经提供)
因此用spring开发web项目 至少需要7个jar:
① spring-aop.jar (开发AOP特性时需要的 jar)[ 注意:web项目的jar包 是存入到WEB-INF/lib中,否则后面可能会报错 ]
IOC容器初始化: web项目启动时 ,会自动加载web.xml,因此需要在web.xml中加载 监听器。
<!-- 指定IOC容器 (applicationContext.xml) 的位置-->
<context-param>
<!-- 监听器的父类ContextLoader中有一个属性contextConfigLocation,该属性值保存着容器配置的文件applicationContext.xml -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<!-- 配置spring-web.jar提供的监听器,此监听器可以在服务器启动时 初始化IOC容器
初始化IOC容器 (applicationContext.xml)
1:必须告诉监听器此容器的位置:context-param
2:默认约定的位置:WEB-INF/applicationContext.xml (xml文件名也不能改)
-->
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
将 applicationContext.xml 放在默认约定的位置:WEB-INF/applicationContext.xml
(xml文件名也不能改)
<listener>
<!-- 配置spring-web.jar提供的监听器,此监听器可以在服务器启动时 初始化IOC容器
初始化IOC容器 (applicationContext.xml)
1:必须告诉监听器此容器的位置:context-param
2:默认约定的位置:WEB-INF/applicationContext.xml (xml文件名也不能改)
-->
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 指定IOC容器 (applicationContext.xml) 的位置 --> <context-param> <!-- 监听器的父类ContextLoader中有一个属性contextConfigLocation,该属性值保存着容器配置的文件applicationContext.xml --> <param-name>contextConfigLocation</param-name> <param-value> classpath:applicationContext.xml, classpath:applicationContextDao.xml, classpath:applicationContextService.xml, classpath:applicationContextController.xml </param-value> </context-param> <listener> <!-- 配置spring-web.jar提供的监听器,此监听器可以在服务器启动时 初始化IOC容器 初始化IOC容器 (applicationContext.xml) 1:必须告诉监听器此容器的位置:context-param 2:默认约定的位置:WEB-INF/applicationContext.xml (xml文件名也不能改) --> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
运行结果:
<!-- 指定IOC容器 (applicationContext.xml) 的位置 --> <context-param> <!-- 监听器的父类ContextLoader中有一个属性contextConfigLocation,该属性值保存着容器配置的文件applicationContext.xml --> <param-name>contextConfigLocation</param-name> <param-value> classpath:applicationContext*.xml, </param-value> </context-param> <listener> <!-- 配置spring-web.jar提供的监听器,此监听器可以在服务器启动时 初始化IOC容器 初始化IOC容器 (applicationContext.xml) 1:必须告诉监听器此容器的位置:context-param 2:默认约定的位置:WEB-INF/applicationContext.xml (xml文件名也不能改) --> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
运行结果:
其他配置文件 在 主配置文件 applicationContext.xml中 使用 <import resource=""/>
加入
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。