xml的配置
在src目录中创建xml文件,命名自定
在xml中添加代码
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns="http://www.springframework.org/schema/beans"
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">
<!--配置一个bean 相当于创建一个UserService对象-->
<bean id="userService" class="cn.itcast.service.UserServiceImpl">
<!--通过IcO(依赖注入)注入-->
<property name="name" value="zhangsan"></property>
</bean>
</beans>
IoC的使用(案例)
创建IUserService接口
public interface IUserService {
public void add();
}
创建UserServiceImpl实现类
public class UserServiceImpl implements IUserService {
@Override
public void add() {
System.out.println("创建用户...");
}
}
在beans中添加
<bean id="userService" class="com.gxq.service.UserServiceImpl"></bean>
创建测试类Lesson并添加
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
IUserService service= (IUserService) context.getBean("userService");
service.add();
}
从.mxl中获取bean
第一种通过ClassPathXmlApplicationContext获取(常用)
ApplicationContext context = new ClassPathXmlApplicationContext("xml文件名);
UserService userService = (强转为xxx对象) context.getBean("bean中的id值");
userService.add();//调用方法
第二种通过xml文件的真实目录获取
ApplicationContext context = new FileSystemXmlApplicationContext("D:\\spring\\day01_spring1\\src\\beans.xml");
UserService userService = (强转为xxx对象) context.getBean("bean中的id值");
userService.add();//调用方法
第三种使用BeanFactory获取(过时)
BeanFactory factory = new XmlBeanFactory(new
FileSystemResource("D:\\spring\\day01_spring1\\src\\beans.xml"));
UserService userService = (UserService) factory.getBean("userService");userService.add();
构造方法默认优先执行
Spring内部创建对象的原理
- 解析xml文件,获取类名、id、属性
- 通过反射,用类型创建对象
- 给创建的对象赋值
装配bean的三种方式
第一种方式:new 实现类
<bean id="userService1" class="cn.itcast.service.UserServiceImpl"></bean>
第二种方式:通过静态工厂方法
// 静态工厂中的方法
public static UserService createUserSerice(){
return new UserServiceImpl();
}
<!--xml中的bean-->
<bean id="userService2" class="静态工厂的位置" factory-method="createUserSerice"></bean>
静态方法调用两次
第三种方式:通过实例工厂方法
//实例工厂中的方法
public UserService createUserSerice(){
return new UserServiceImpl();
}
<!--xml中的bean-->
<bean id="factory2" class="实例工厂的位置"></bean>
<bean id="userService3" factory-bean="factory2" factory-method="createUserSerice"></bean>
静态方法调用三次
DI依赖注入
<bean id="userService1" class="cn.itcast.service.UserServiceImpl">
<property name="name" value="zs"></property>//依赖注入
</bean>
bean的作用域
设置方法:scope属性
<bean id="userService1" class="cn.itcast.service.UserServiceImpl"
scope="prototype"></bean>
singleton:在Spring IoC容器中仅存在一个Bean实例,Bean以单例方式存在,内存地址相同;默认值
prototype:每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时 ,相当于执行new XxxBean(),内存地址不同
bean的生命周期
[外链图片转存失败(img-M4XuH5Ny-1564896745849)(en-resource://database/888:1)]
生命周期图解释
1.instantiate bean对象实例化
2.populate properties 封装属性
3.如果Bean实现BeanNameAware 执行 setBeanName:创建对象的名称
4.如果Bean实现BeanFactoryAware 执行setBeanFactory ,获取Spring容器:bean工厂
5.如果存在类实现 BeanPostProcessor(预处理Bean) ,执行postProcessBeforeInitialization
6.如果Bean实现InitializingBean 执行 afterPropertiesSet :属性赋值完成
7.调用 指定初始化方法 init:自定义初始化方法
8.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessAfterInitialization
执行业务处理
9.如果Bean实现 DisposableBean 执行 destroy:销毁bean对象
10.调用 指定销毁方法 customerDestroy
11.销毁bean对象(关闭容器):service.getClass().getMethod(“close”).invoke(context);
给对象的属性赋值
方法一:通过构造方法注入(前提是Student中有构造方法)
<bean id="stu" class="cn.itcast.model.Student">
<constructor-arg name="username" value="zhangsanz"></constructor-arg>
<constructor-arg name="password" value="123"></constructor-arg>
</bean>
方法二:通过索引和类型注入
<bean id="stu" class="cn.itcast.model.Student">
<constructor-arg index="0" value="zangsan" type="java.lang.String"></constructor-arg>
<constructor-arg index="1" value="20" type="int"></constructor-arg>
</bean>
方法三:通过set方法注入
<bean id="stu" class="cn.itcast.model.Student">
<property name="username" value="zhangsan"></property>
<property name="password" value="zhangsan"></property>
<property name="age" value="20"></property>
</bean>
方法四:p命名空间注入(依赖于set方法)
- 在头部加上
xmlns:p="http://www.springframework.org/schema/p"
- 注入
<bean id="stu" class="cn.itcast.model.Student" p:username="zs" p:password="ls" p:age="23"></bean>
spEL
格式:
类型:
#{123}、#{‘jack’} : 数字、字符串
#{beanId} :另一个bean引用
#{beanId.propName} :操作数据
#{beanId.toString()} :执行方法
#{T(类).字段|方法} :静态方法或字段
好处:可以调用方法
如:<property name="name" value="#{'zhangsan'.toUpperCase()}"></property>
<property name="pi" value="#{T(java.lang.Math).PI}"></property>
集合的注入
<-- list的注入 -->
<bean id="programmer" class="cn.itcast.model.Programmer">
<property name="cars">
<list>
<value>领克</value>
<value>凯迪拉克</value>
</list>
</property>
<-- set的注入 -->
<property name="pats">
<set>
<value>dudou</value>
<value>kity</value>
</set>
</property>
<-- map -->
<property name="house">
<map>
<entry key="山东" value="碧桂园"></entry>
<entry key="北京" value="四合院"></entry>
</map>
</property>
<-- Properties -->
<property name="mysqlInfos">
<props>
<prop key="url">mysql:jdbc://localhost:3306/pos</prop>
<prop key="root">root</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
注解的使用
-
@Repository(“名称”):dao层
-
@Service(“名称”):service层
-
@Controller(“名称”):web层
-
@Autowired:自动根据类型注入
-
@Qualifier(“名称”):指定自动注入的id名称
-
@Resource(“名称”)
-
@ PostConstruct 自定义初始化方法
-
@ PreDestroy 自定义销毁方法
在需要创建对象的类开头添加@Component(“id”)
在xml中添加<context:annotation-config/>
<context:component-scan base-package="cn.itcast"/>
创建对象时:
ApplicationContext context = new ClassPathXmlApplicationContext("xxxx.xml");
UserService service = (UserService) context.getBean("id"); //有id时使用
UserService service = (UserService) context.getBean(实现类名.class);
AOP
JDK动态代理
必须是继承接口的实现类才能使用AOP
cglib增强字节码
可以用于继承接口的实现类和普通类
AOP半自动编程
导入AOP联盟jar包:com.springsource.org.aopalliance-1.0.0
AOPjar包:spring-aop-3.2.10.RELEASE
目标类接口
public interface IUserService {
public void add();
}
目标类实现类
public class UserServiceImpl implements IUserService {
@Override
public void add() {
System.out.println("创建用户"+name);
}
}
测试类
public class Lessin07 {
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans7.xml");
IUserService service = (IUserService) context.getBean("sevriceProxy");
service.add();
}
}
MyAspect切面类
public class MyAspect implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//拦截方法
System.out.println("开启事务");
//放行
Object retObj = mi.proceed();
System.out.println("拦截....");
System.out.println("提交事务");
return retObj;
}
}
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"
xmlns:context="http://www.springframework.org/schema/context"
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">
<!--配置userservice-->
<bean id="userService" class="com.gxq.service.UserServiceImpl"></bean>
<!--配置切面类-->
<bean id="myAspect" class="com.gxq.service.MyAspect"></bean>
<!--配置代理对象-->
<bean id="sevriceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--接口-->
<property name="interfaces" value="com.gxq.service.IUserService"/>
<!--目标对象-->
<property name="target" ref="userService"></property>
<!--切面类-->
<property name="interceptorNames" value="myAspect"></property>
</bean>
</beans>
AOP全自动编程
导入com.springsource.org.aspectj.weaver-1.6.8.RELEASE依赖jar包
在xml头部添加
xmlns:aop="http://www.springframework.org/schema/aop
//在xsi:schemaLocation中
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
<bean id="userService" class="cn.itcast.service.UserServiceImpl"></bean>
<!-- 配置切面类对象-->
<bean id="myAspect" class="cn.itcast.service.MyAspect2"></bean>
<!-- 全自动AOP配置
1.在bean中配置aop约束
2.配置aop:config内容,把切入点和通知结合 proxy-target-class:
使用cglib实现代理 expression 表达式:*任意
execution(* com.gyf.service.*. * (..)) :返回值 包名 类名 方法名 参数 -->
<aop:config proxy-target-class="true">
<!-- 切入点: expression:表达式 每个service的方法前面都开启事务和结束事务
AOP:用于事务配置&日志记录 -->
<aop:pointcut id="myPointcut" expression="execution (* cn.itcast.service.UserServiceImpl.deleteUser())"/>
<!-- 通知 关联 切入点-->
<aop:advisor advice-ref="myAspect" pointcut-ref="myPointcut" ></aop:advisor>
</aop:config>·
AspectJ
导入jar包:spring-aspects-3.2.10.RELEASE
xml中添加代码
<!--配置userservice-->
<bean id="userService" class="com.gxq.service.UserServiceImpl"></bean>
<!--配置切面类-->
<bean id="myAspect3" class="com.gxq.aspect.MyAspect3"></bean>
<!--配置AOP-->
<aop:config>
<!--aop指定切面-->
<aop:aspect ref="myAspect3">
<!--配置切入点-->
<aop:pointcut id="myPointcut" expression="execution(* com.gxq.service.UserServiceImpl.*(..))"/>
<!--配置前置通知-->
<!--<aop:before method="myBefore" pointcut-ref="myPointcut"/>-->
<!--配置后置通知-->
<!--<aop:after-returning method="myAfterReturning" pointcut-ref="myPointcut"/>-->
<!--配置环绕通知-->
<aop:around method="myAround" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config>
切面类:
public class MyAspect3 {
//前置
public void myBefore(){
System.out.println("前置通知");
}
//后置
//如果service有返回值,则添加Object retValue形参,在xml中添加returning="retValue"属性
public void myAfterReturning(){
System.out.println("后置通知");
}
//环绕
public Object myAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知");
System.out.println("前置通知");
// 放行
Object retObj = pjp.proceed();
System.out.println("后置通知");
return retObj;
}
}
AspectJ的注解
切面类中添加:@Component和@Aspect两个注解
service类中添加:@Service(“id”)注解
xml文件中代码:
<context:component-scan base-package="com.gxq"/>
<aop:aspectj-autoproxy/>
<aop:config>
//ref值为切面类名称首字母小写
<aop:aspect ref="myAspect"></aop:aspect>
</aop:config>
测试类中代码:
ApplicationContext context = new ClassPathXmlApplicationContext("xml文件名");
IUserService service = (IUserService) context.getBean("serviceID名");
//调用方法
service.add(1);
@Aspect 声明切面,修饰切面类,从而获得 通知。
通知
@Before 前置
@AfterReturning 后置
@Around 环绕
@AfterThrowing 抛出异常
@After 最终
切入点
@PointCut ,修饰方法 private void xxx(){} 之后通过“方法名”获得切入点引用
数据库操作
c3p0 及 JdbcTemplate
导入包:com.springsource.org.apache.commons.dbcp-1.2.2.osgi
com.springsource.org.apache.commons.pool-1.5.3
mysql-connector-java-5.1.37-bin
spring-jdbc-3.2.10.RELEASE
spring-tx-3.2.10.RELEASE
UserDaoImpl继承IUserDao
public class UserDaoImpl implements IUserDao {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
} @Override
public void add(User user) {
System.out.println("userDao添加用户"+user);
jdbcTemplate.update("insert into t_user (username,password) values
(?,?)",user.getUsername(),user.getPassword());
}
}
dao中添加
public class UserDaoImpl implements IUserDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void add(User user) {
jdbcTemplate.update("insert t_user(username,password) values (?,?)",user.getUsername(),user.getPassword());
}
c3p0的配置文件.properties
driverClass=com.mysql.jdbc.Driverjdbc
Url=jdbc:mysql:///spring_day04
user=root
password=123456
在xml中添加
<!--JdbcTemplate配置DataSource-->
<!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring_day04"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean> -->
<!-- c3p0配置DataSource-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"/>
<property name="user" value="${user}"/>
<property name="password" value="${password}/>
</bean>
<!-- 配置jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置dao -->
<bean id="userDao" class="com.gxq.dao.UserDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
测试类
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans05.xml");
IUserDao userDao = (IUserDao) context.getBean("userDao");
User user = new User();
user.setUsername("zzm");
user.setPassword("123");
userDao.add(user);
}
事务操作
AOP的事务配置
<!--jdbc配置-->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"/>
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
</bean>
<bean id="accountDao" class="com.gxq.dao.Impl.AccoutDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--配置DataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置service-->
<bean id="accountService" class="com.gxq.service.AccountService">
<property name="accountDao" ref="accountDao"></property>
</bean>
<!--配置通知事务管理器-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!--事务详情: 传播行为 隔离级别-->
<tx:attributes>
<tx:method name="service中的方法名" propagation="REQUIRED" isolation="DEFAULT"/>
。
。可以多个
。
</tx:attributes>
</tx:advice>
<!--切入点链接通知事务管理器-->
<aop:config>
<aop:pointcut id="myPointCut" expression="execution(* com.gxq.service..*.*(..))">
</aop:pointcut>
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointCut">
</aop:advisor>
</aop:config>
通过注解进行事务配置
xml中
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"/>
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
</bean>
<bean id="accountDao" class="com.gxq.dao.Impl.AccoutDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置service-->
<bean id="accountService" class="com.gxq.service.AccountService">
<property name="accountDao" ref="accountDao"></property>
</bean>
<!--配置事务管理器-->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--配置DataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--切入点链接通知事务管理器-->
<tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven>
在service中添加@Transactional注解
- 属性可以在其后的()中写,不写则为默认值
- 根据位置确定作用域,在类名上面写,整个类的所有方法都起作用;在方法名上面写,只有这一个方法起作用
spring Servlet的整合
在src目录中创建applicationContext.xml
并添加spring的配置代码
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>
在web.xml中添加
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
servlet
//加载applicationContext.xml文件
ApplicationContext context =
WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
//通过bean创建类
userService = (IUserService) context.getBean("userService");
//调用方法
userService.add(username);