Spring
1.Spring是轻量级的开源的javaEE框架
2.Spring可以解决企业应用开发的复杂性
3.Spring有两个核心部分ioc和aop
(1)ioc:控制反转,把创建对象过程交给spring进行管理
(2)aop:面向切面,不修改源代码进行功能增强
IOC操作Bean管理(bean生命周期)
-
生命周期
(1)从对象创建到对象销毁的过程 -
bean生命周期
(1)通过构造器创建bean实例(无参数构造)
(2)为bean的属性设置值和对其他bean引用(调用set方法)
(3)调用bean的初始化的方法(需要进行配置初始化的方法)
(4)bean可以使用了(对象获取到了)
(5)当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法) -
创建 init-method=“initMethod”
销毁 destroy-method=“destroyMethod”
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
">
<bean id="myBean" class="com.tom.spring5.bean.Orders" init-method="initMethod" destroy-method="destroyMethod">
<property name="oname" value="手机"></property>
</bean>
</beans>
public class Orders {
private String oname;
//无参构造
public Orders() {
System.out.println("第一步 执行无参数构造创建bean实例");
}
public void setOname(String oname) {
this.oname = oname;
System.out.println("第二步 调用set方法设置属性值");
}
//创建执行的初始化的方法
public void initMethod(){
System.out.println("第三步 执行初始化的方法");
}
//创建执行的销毁的方法
public void destroyMethod(){
System.out.println("第五步 执行销毁的方法");
}
}
@Test
public void testCollection4(){
// ApplicationContext context=new ClassPathXmlApplicationContext("bean4.xml");
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean4.xml");
Orders orders=context.getBean("myBean", Orders.class);
System.out.println("第四步 获取创建bean实例对象");
System.out.println(orders);
//手动让bean实例销毁
((ClassPathXmlApplicationContext)context).close();
}
4.bean的后置处理器,bean生命周期有七步
(1) 通过构造器创建bean实例(无参数构造)
(2)为bean的属性设置值和对其他bean引用(调用set方法)
(3)把bean实例传递bean后置处理器的方法
postProcessBeforeInitialization
(4)调用bean的初始化方法(需要进行配置初始化的方法)
(5)把bean实例传递bean后置处理器的方法
postProcessAfterInitialization
(6)bean可以使用了
(7)当容器关闭的时候,调用bean的销毁方法
5.IOC操作bean管理(xml自动装配)
- 什么是自动装配?
根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入
<!--实现自动装配
bean标签属性autowire,配置自动装配,不过通常使用注解的方式
autowire属性常用两个值:
byName根据属性名称注入,注入值bean的id值和类属性名称一样
byType根据属性类型注入
-->
<bean id="emp" class="com.tom.spring5.autowire.Emp" autowire="byType">
<!--<property name="dept" ref="dept"></property>-->
</bean>
<bean id="dept" class="com.tom.spring5.autowire.Dept"></bean>
IOC操作Bean管理(基于注解方式)
- 什么是注解
(1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值…)
(2)使用注解,注解作用在类上面,方法上面,属性上面
(3)使用注解的目的,简化XML配置
2.spring针对Bean管理中创建对象提供注解
@Component
@Service
@Controller
@Repository
*上面四个注解功能是一样的,都可以用来创建bean实例
基于注解方式实现对象创建
1.引入依赖(jar包)
spring-aop-5.2.6.RELEASE.jar
2.开启组件扫描
<!--开启组件扫描
1.如果扫描多个包,多个包使用逗号隔开
2.扫描包上层目录
-->
<context:component-scan base-package="com.tom."></context:component-scan>
3.基于注解方式创建对象
4.
<!--实例1
use-default-filters="false" 表示现在不使用默认filter,自己配置filter
context:include-filter 设置扫描那些内容
-->
<context:component-scan base-package="com.tom" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--实例2
context:include-filter 设置那些内容不进行扫描
-->
<context:component-scan base-package="com.tom">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
5.基于注解方式实现属性注入
@Autowired:根据属性类型进行自动装配
@Qualifier:根据属性名称进行注入
@Resource:可以根据类型注入,可以根据名称注入
@Value:注入普通类型属性
@Repository
public class UserDaoImpl implements UserDao{
//定义dao类型属性
//不需要添加set方法
//添加注入属性注解
@Autowired //根据类型注入
private UserDao userDao;
@Override
public void add() {
System.out.println("service add......");
userDao.add();
}
}
@Repository(value = "userDaoImpl1")
public class UserDaoImpl implements UserDao{
//定义dao类型属性
//不需要添加set方法
//添加注入属性注解
@Autowired //根据类型注入
@Qualifier(value = "userDaoImpl1")//根据名称注入,必须和Autowired一起使用
private UserDao userDao;
@Override
public void add() {
System.out.println("service add......");
userDao.add();
}
}
//@Resource //根据类型进行注入
@Resource(name="userDaoImpl1")//根据名称进行注入
private UserDao userDao;
@Value(value = "wuwei")
private String nname;
AOP(面向切面编程)
1.什么是AOP
面向切面编程,利用aop可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率.
通俗描述:不通过修改源代码方式,在主干功能里面添加新功能.
2.AOP底层
AOP底层使用动态代理
(1)有两种情况动态代理
第一种 有接口情况,使用JDK动态代理
1.创建UserDao接口实现类代理对象,该代理对象和该类Impl的区别是
该类UserDao对象不是new出来的,但是具有和new出来的有同样的功能
第二种 没有接口情况,使用CGLIB动态代理
1.创建当前子类的代理对象,增强类的方法
3.动态代理java.lang.reflect.Proxy
newProxyInstance
public static Object newProxyInstance(ClassLoader loader,
类<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。
Proxy.newProxyInstance因为与IllegalArgumentException相同的原因而Proxy.getProxyClass 。
参数
loader - 类加载器来定义代理类
interfaces - 代理类实现的接口列表
h - 调度方法调用的调用处理函数
结果
具有由指定的类加载器定义并实现指定接口的代理类的指定调用处理程序的代理实例
异常
IllegalArgumentException - 如果对可能传递给 getProxyClass有任何 getProxyClass被违反
SecurityException -如果安全管理器,S存在任何下列条件得到满足:
给定的loader是null ,并且调用者的类加载器不是null ,并且调用s.checkPermission与RuntimePermission("getClassLoader")权限拒绝访问;
对于每个代理接口, intf ,呼叫者的类加载器是不一样的或类加载器的祖先intf和调用s.checkPackageAccess()拒绝访问intf ;
任何给定的代理接口的是非公和呼叫者类是不在同一runtime package作为非公共接口和调用s.checkPermission与ReflectPermission("newProxyInPackage.{package name}")权限拒绝访问。
NullPointerException - 如果 interfaces数组参数或其任何元素是 null ,或者如果调用处理程序 h是 null