Spring两大核心思想IOC,AOP

Spring框架

Spring框架是个轻量级的java EE框架。所谓轻量级,是指不依赖于容器就能运行。Spring以IOC,AOP为主要思想,能够协同Struts,Hibernate,WebWork,JSF,iBatis等众多框架

Spring解决的主要问题

1 Spring的IOC容器降低了业务对象替换的复杂性,提高了组件之间的解耦。提升了代码的灵活性,可维护性高
2 Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用。
3 Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问。
4 Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部。

IOC

IOC概念

Spring最重要思想之一IOC(Inversion of Control控制反转),或者称为DI(Dependency Injection,依赖注入)。就是将我们需要的对象实例化之后交给Spring来统一管理,哪些地方需要就对哪里依赖注入

IOC的优势

实现组件之间的解耦,就是降低了类与类之间的耦合度。提高程序的灵活性和可维护性

IOC实例化的方式
1 无参构造方法

这种方式需要系统默认的无参构造,声明的对象也要有setter方法

<!-- 在xml中   无参构造方法-->
    <bean id="userdao" class="com.woniuxy.dao.Userdao"></bean>
    <bean id="userservice" class="com.woniuxy.service.Userservice">
<!--    在下面进行依赖的注入-->
        <property name="userdao" ref="userdao"></property>
    </bean>
    <bean id="controller" class="com.woniuxy.controller.Controller">
        <property name="userservice" ref="userservice"/>
    </bean>
2 静态工厂方法

这种方法必须类中的方法为静态方法,我们通过调用这个方法,返回的实例化就可以直接赋给id,不是clas的实例,而是方法返回的实例

<!--在xml中    静态工厂方法创建-->
    <bean id="userFactory" factory-method="getM" class="com.woniuxy.controller.FactorMathod" ></bean>
3 实例工厂方法

这种方法需要先有一个bean的实例,然后通过调用这个bean的方法返回一个新的实例,来作为这个bean的实例

<!--在xml中    工厂bean实例化-->
    <bean id="factoryMethod" class="com.woniuxy.controller.FactorMathod"></bean>
    <bean id="getuser" factory-bean="factoryMethod" factory-method="getU"></bean>
4 实现FactoryBean接口方法

需要先实现FactoryBean接口,然后重写方法,在object方法中返回对象,来作为这个bean的实例
java代码

public class TestInterface implements FactoryBean<Userdao> {
    @Override
    public Userdao getObject() throws Exception {
        return new Userdao();
    }

    @Override
    public Class<?> getObjectType() {
        return Userdao.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}

下面是xml

<!--在xml中    Spring的FactoryBean接口实例化-->
    <bean id="getInterface" class="com.woniuxy.controller.TestInterface"></bean>
IOC的依赖注入方式
1 构造方法的方式注入
<bean id="car" class="cn.itcast.spring.demo4.Car">

<constructor-arg name="name" value="保时捷"/>

<constructor-arg name="price" value="1000000"/>

<bean>
2 set 方法的方式注入
<bean id="car2" class="cn.itcast.spring.demo4.Car2">

<property name="name" value="奇瑞 QQ"/>

<property name="price" value="40000"/>

<bean> 
Bean的生命周期

(1)、xml中指定初始化(init-method)和销毁(destory-method)的方法

<bean id="person" class="domain.Person" init-method="" destroy-method="">

(2)、实现initiializingBean接口,初始化。实现disposableBean接口,销毁

Bean的作用域
  • 默认情况下,bean的作用域是单例的(singleton),也就是spring的应用上下文中只能有一个bean实例,创建一次。
  • 原型(prototype),每次注入或者通过spring容器获取bean的时候都会重新创建一个bean实例。
  • 会话(session),web应用中,针对每个会话创建一个bean实例。
  • 请求(request),web应用中,针对每个请求创建一个bean实例
  • 链接(websocket) ,web应用中,针对每个链接创建一个bean实例

IOC的三种配置方法

在这之前需要导入Spring context的jar包,以及一些自己需要的包
1 XML配置

主要是将bean信息配置到xml文件中,让Spring对配置的类进行实例,然后放入容器中,最后再进行依赖注入
首先在resources文件中创建一个applicationconfig.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    最常用的声明-->
    <bean id="userdao" class="com.woniuxy.dao.Userdao"></bean>
    <bean id="userservice" class="com.woniuxy.service.Userservice">
<!--    在下面进行依赖的注入-->
<!--   注意 这种方法需要java类中有setter方法,name为变量名 --!>
        <property name="userdao" ref="userdao"></property>
    </bean>
    <bean id="controller" class="com.woniuxy.controller.Controller">
        <property name="userservice" ref="userservice"/>
    </bean>
<!--    静态工厂方法创建,这个必须要java方法为静态方法-->
    <bean id="userFactory" factory-method="getM" class="com.woniuxy.controller.FactorMathod" ></bean>
<!--    工厂bean实例化,需要方法有具体返回-->
    <bean id="factoryMethod" class="com.woniuxy.controller.FactorMathod"></bean>
    <bean id="getuser" factory-bean="factoryMethod" factory-method="getU"></bean>

<!--    Spring的FactoryBean接口实例化,java类要实现FactoryBean接口,重写方法,并在object方法中返回实例作为这个bean的实例-->
    <bean id="getInterface" class="com.woniuxy.controller.TestInterface"></bean>

<!--    构造器注入-->
    <bean id="person" class="com.woniuxy.controller.Person">
        <constructor-arg index="0" value="张三"/>
        <constructor-arg index="1" value="20"/>
        <constructor-arg index="2">
            <list>
                <value>11111</value>
                <value>12222</value>
                <value>13333</value>
                <value>14444</value>
            </list>
        </constructor-arg>
    </bean>
</beans>

xml配置文件中我们通过property对依赖进行了注入,这种方法需要类中有setter方法才可以,并且类中已经声明了该对象,
也可以通过java代码读取配置文件来调用他的bean方法,最后获取一个实例

//通过读取方式获得
ClassPathXmlApplicationContext cc = new ClassPathXmlApplicationContext("applicationContext.xml");
//然后就可以通过他的getBean方法获取我们需要的实例了
Controller controller = cc.getBean("controller", Controller.class);

上面这种java中直接获取getBean方法中,第一个参数为id名,第二个参数为类的实例,如果不写则返回object对象

2 注解声明配置

下面说一种代码量比较少的方式,使用注解来实现
同样先在resources文件下创建一个 applicationcofig.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: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">
       <!-- 下面就是让spring对base-package中的包路径进行扫描,他们根据注解来辨别我们的需求,自动加入依赖 --!>
    <context:component-scan base-package="com.woniuxu.spring"/>
</beans>

有了上面的配置信息之后,我们就可以在需要的类上面加入注解对其进行实例化了
@Controller 是加在controlle层中的类上面的
@Service 是加在service层 中的类上面的
@Repository 是加在dao层的类上面的
@Component 其他注解,不在上面这个三个中的注解,加上之后也会进行读取,具体用法下面会说到
@Autowired 自动注入依赖,加在声明的对象上面即可

@Scope(“作用域”) 里面填写作用域,可以进行修改
@PostConstruct 加在方法上面,为生命周期的开始
@RreDestroy 加在方法上面,为生命周期的结束

下面给出一个简单的类注解方式

@Repository
public class UserDao {
    @Autowired
    private QueryRunner qr ;

    public User getUser(String username, String password) {
        try {
            return qr.query("select * from user where username = ? and password = ? ", new BeanHandler<User>(User.class), username, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null ;
    }
}

由于我写的这个类是dao层的所以加了@Repository,其他根据具体使用相应注解在这里插入代码片

3 JavaConfig声明配置

下面介绍一种纯java代码实现方法
这儿我们就不需要创建xml文件了,而是用java的类来替代了
1 首先创建一个用来配置的java类,然后在类上面加入@Configuration注解,代表这个类为我们的配置类
2 然后写方法,方法的名字就相当于我们xml中配置的bean的id名,方法上面一定要加入@Bean注解,这样才能表示为一个bean
3 同样的也需要对我们的每个层加入对应的注解,需要的实例任然要有setter方法
@Controller 是加在controlle层中的类上面的
@Service 是加在service层 中的类上面的
@Repository 是加在dao层的类上面的
@Component 其他注解,不在上面这个三个中的注解,加上之后也会进行读取,具体用法下面会说到
@Autowired 自动注入依赖,加在声明的对象上面即可

下面给出一个例子

@Configuration
public class Appconfig {
    @Bean
    public Controllers1 controller(UserService userService){
        Controllers1 controllers1 = new Controllers1();
        controllers1.setUserService(userService);
        return controllers1 ;
    }

    @Bean
    public UserService userService(UserDao userDao){
        UserService userService = new UserService();
        userService.setUserDao(userDao);
        return userService ;
    }
    @Bean
    public UserDao userDao(QueryRunner qr){
        UserDao userDao = new UserDao();
        userDao.setQr(qr);
        return userDao ;
    }
 }

如果觉得上面的方法太麻烦也可以这样
在这个类上面加上@ComponentScan(“包路径”) 让他对这个包路径进行扫描来自动实例化我们需要的对象,这样就不需要setter方法,也不需要写bean方法了

@Configuration
@ComponentScan("com.woniuxu.spring")
public class Appconfig {
}

以上就是IOC三种配置方法了

AOP

AOP的概念

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

AOP应用场景

AOP用来封装横切关注点,具体可以在下面的场景中使用

Authentication 权限

Caching 缓存

Context passing 内容传递

Error handling 错误处理

Lazy loading 懒加载

Debugging 调试

logging, tracing, profiling and monitoring 记录跟踪 优化 校准

Performance optimization 性能优化

Persistence 持久化

Resource pooling 资源池

Synchronization 同步

Transactions 事务

AOP配置方式

1 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    配置service-->
    <bean id="service" class="com.woniuxy.aop.service.UserService"></bean>
<!--    配置通知-->
    <bean id="aopconfig" class="com.woniuxy.aop.AOPConfig"></bean>

<!--    配置切入点-->
    <bean id="aspect" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
        <property name="pattern" value="com.woniuxy.aop.service.UserService.addUser"></property>
    </bean>
<!--    配置切面-->
    <bean id="cutpoint" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <property name="pointcut" ref="aspect"></property>
        <property name="advice" ref="aopconfig"></property>
    </bean>
<!--    包装service类-->
    <bean id="creator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>

</beans>

这种配置方式使用bean,配置过程比较复杂,代码量较多,下面给出一种稍微简化的

<?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: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/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <bean id="userDao" class="com.woniuxy.aop.dao.impl.UserDaoImpl"></bean>
    <bean id="txAOP" class="com.woniuxy.aop.TransactionAOP"></bean>
<!--    切面-->
    <aop:config>
        <aop:aspect ref="txAOP">
<!--            扫包-->
            <aop:pointcut id="daoPointcut" expression="execution(* com.woniuxy.aop.dao.impl.*.*(..))"/>
            
            <aop:before method="TxStart" pointcut-ref="daoPointcut"/>
            <aop:after-returning method="TxCommit" pointcut-ref="daoPointcut"/>
            <aop:after-throwing method="TxRollBack" pointcut-ref="daoPointcut"/>
        </aop:aspect>
    </aop:config>

    <context:component-scan base-package="com.woniuxy.aop"/>
    <aop:aspectj-autoproxy/>


</beans>
2 注解方式
@Component
@Aspect
public class Txconfig {
    @Pointcut("execution(* com.woniuxy.aop.dao.impl.*.*(..))")
    public void pointecut(){

    }
    @Around("pointecut()")
    public Object around(ProceedingJoinPoint pj) {
        System.out.println("开启事物");
        Object[] args = pj.getArgs();
        Object proceed = null ;
        try {
            proceed = pj.proceed(args);
            System.out.println("提交事物");
        } catch (Throwable throwable) {
            System.out.println("回滚事物");
        }
        return proceed ;
    }
}

上面的代码是根据对应方法加上注解,还需在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: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">
       <!-- 下面就是让spring对base-package中的包路径进行扫描,他们根据注解来辨别我们的需求,自动加入依赖 --!>
    <context:component-scan base-package="com.woniuxu.spring"/>
</beans>

这样才可以做到自动扫包

3 java配置方式

顾名思义就是不使用xml全部统一使用java代码表写,配置每个层和前面提到的IOC里面的注解一样,

@Component
@Aspect
public class Txconfig {
    @Pointcut("execution(* com.woniuxy.aop.dao.impl.*.*(..))")
    public void pointecut(){

    }
    @Around("pointecut()")
    public Object around(ProceedingJoinPoint pj) {
        System.out.println("开启事物");
        Object[] args = pj.getArgs();
        Object proceed = null ;
        try {
            proceed = pj.proceed(args);
            System.out.println("提交事物");
        } catch (Throwable throwable) {
            System.out.println("回滚事物");
        }
        return proceed ;
    }
}

这里是我们要环绕的类,@Around ,然后需要配置一个自动扫包的的配置类

@Configuration
@ComponentScan("com.woniuxy.aop")
@EnableAspectJAutoProxy
public class AutoWirted {
}

这个类就比较简单了,这要是
@Configuration说明这个配置类
@ComponentScan(“com.woniuxy.aop”)给出我们需要扫包的路径
@EnableAspectJAutoProxy启动
这样就完成了一个纯java的配置了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值