spring

为什么要学习spring?

spring提供了ioc容器,不需要自己创建和管理对象,由spring来创建和管理。

spring提供了面向切面编程,不修改源代码的情况下对功能进行增强。

spring提供了事务支持,使事务操作变得更加方便。

spring方便集成其他框架,例如mybatis。


IOC

控制反转,由spring来创建对象以及对象之间的调用。最主要的作用就是降低耦合度。

对象之间调用的传统方式:

        class A{                                                                             class B{

                add(){                                                                                 put(){}

                        B b = new B();                                                     }

                        b.put();

                }

             }

工厂模式:

        

        class A{                                                                             class B{

                add(){                                                                                 put(){}

                       B b =Factory.getB()                                                   }

                        b.put();

                }

             }

  

           class  Factory{

                public static  B   getB(){

                        return new B();

                }

}

耦合度不可能不存在,只能是降低到最小。


IOC底层原理:

        ioc主要是由xml解析、工厂模式以及反射实现的。

        1.在xml文件里配置要创建的对象

        <bean id="别名" class="类路径"></bean>

        2.创建工厂类

        class  Factory{

                public static  B   getB(){

                        String classValue  =类路径   //这是由xml解析得到的

                        Class clazz  =Class.forName(classValue);  //反射机制,通过类名得到该类的字节码文件

                        return (强转)clazz.newInstance();  //newInstance()方法默认调用类的空参构造器创建对象

                }

ioc容器底层的本质就是对象工厂。


基于注解方式创建对象以及注入属性

创建对象的注解

@Component       普通组件

@Controller          用于web层

@Service              用于业务逻辑层

@Repository         用于持久层(数据层)

属性注入(对象类型的属性)

@AutoWired  (最常用)   根据属性类型自动注入

@Qualifier         根据属性名称注入,这个注解需要和@AutoWired 一起使用,当一个接口有多个实现类,仅@AutoWired无法确定是注入哪个实现类的对象,需要用 @Qualifier (value="类名小写")

@Resource      可以根据类型或名称注入

@AutoWired 和@Resource 的区别:

        @AutoWired默认按照属性类型注入,根据名称需要加@Qualifier 

        @Resource默认按照属性名称注入,名称找不到才会按照属性类型注入。


AOP

面向切面编程

底层原理(动态代理)

1.有接口情况,使用jdk动态代理

public interface UserDao {

    public int add(int a, int b);

    public String update(String id);
}
public class UserDaoImpl implements  UserDao{

    @Override
    public int add(int a, int b) {
        System.out.println("add方法执行了");
        return a+b;
    }

    @Override
    public String update(String id) {
        System.out.println("update方法执行了");
        return id;
    }
}

 创建代理对象需要用到Proxy类的newProxyInstance()方法,三个参数为类加载器,接口,InvocationHandler接口的实现类对象

public class JDKProxy {
    public static void main(String[] args) {

        Class[] interfaces = {UserDao.class};
        UserDaoImpl userDao = new UserDaoImpl();
        //接口等于实现类创建代理对象
        UserDao dao =(UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
        int result =  dao.add(1, 2);
        System.out.println("result"+result);

    }

}
//创建代理对象代码
class UserDaoProxy implements InvocationHandler {

    //把需要增强的方法所在的类的对象传递过来
    //通过有参构造传递
    private Object obj;
    public UserDaoProxy(Object obj) {
        this.obj = obj;
    }


    //增强的逻辑代码
    //proxy代表代理类,method是代理类和被代理的同名方法,args方法参数
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法之前的增加处理
        System.out.println("方法之前执行"+method.getName()+":传递的参数.."+ Arrays.toString(args));

        //被增加的方法的执行
        Object res = method.invoke(obj, args);

        //方法之后的增加处理
        System.out.println("方法之后输出"+obj);
        return res;
    }
}

2.没有接口情况,使用cglib动态代理

public class UserDao {
	public void addUser() {
		System.out.println("添加方法");
	}
	
	public void deleteUser() {
		System.out.println("删除方法");
	}

}
public class CglibProxy implements MethodInterceptor{
	
	//创建代理方法
	public Object createProxy(Object object) {
		//创建一个动态类对象
		Enhancer enhancer = new Enhancer();
		
		//确定需要增强的类 设置其父类
		enhancer.setSuperclass(object.getClass());
		
		//添加回调函数
		enhancer.setCallback(this);
		
		//返回创建的代理类
		return enhancer.create();
	}

	//proxy cglib根据定义的父类生成的代理对象
	//method  拦截的方法
	//args  拦截的方法的参数数组
	//methProxy  方法的代理对象 用于执行父类的方法
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methProxy) throws Throwable {
		
		//方法执行之前
		
		//目标方法执行
		Object obj = methProxy.invokeSuper(proxy, args);
		
		//方法执行之后
		return obj;
	}

}
public class CglibTest {
	public static void main(String[] args) {
		//创建代理对象
		CglibProxy cglibProxy = new CglibProxy(); 
		//创建目标对象
		UserDao userDao = new UserDao();
		//将目标对象传入代理对象中   获取增强后的方法
		UserDao userDao2 = (UserDao) cglibProxy.createProxy(userDao);
		//执行
		userDao2.addUser();
		userDao2.deleteUser();
	}

}


spring的bean默认是单例模式的,可以将singleton改为prototype变为多实例。

单例模式分为懒汉式和饿汉式

        饿汉式单例模式(提前创建好)

                1.首先将类的构造器声明为私有,不能在类外创建对象

                2.声明一个静态属性

                        private static  类名   对象=  new 类名()

                3.写一个静态方法用于返回创建好的一个实例对象

                        public static 类名  getInstance(){

                                return    对象;

                        }

        懒汉式单例模式(要用的时候才创建)(线程不安全,可加synchronized优化)

                1.同样将构造器定义为私有

                2.声明静态变量,不赋对象

                3.在静态方法中给静态变量赋一个new对象,然后返回。

                 但是在静态方法中需要判断是不是已经new了对象,若没有则创建,有则使用原来的。不加判断会导致每次都是一个地址不同的对象

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值